Java方法的静态绑定与动态绑定讲解(向上转型的运行机制详解)
转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6554103.html
一:绑定
把一个方法与其所在的类/对象 关联起来叫做方法的绑定。绑定分为静态绑定(前期绑定)和动态绑定(后期绑定)。
二:静态绑定
静态绑定(前期绑定)是指:在程序运行前就已经知道方法是属于那个类的,在编译的时候就可以连接到类的中,定位到这个方法。
在Java中,final、private、static修饰的方法以及构造函数都是静态绑定的,不需程序运行,不需具体的实例对象就可以知道这个方法的具体内容。
三:动态绑定
动态绑定(后期绑定)是指:在程序运行过程中,根据具体的实例对象才能具体确定是哪个方法。
动态绑定是多态性得以实现的重要因素,它通过方法表来实现:每个类被加载到虚拟机时,在方法区保存元数据,其中,包括一个叫做 方法表(method table)的东西,表中记录了这个类定义的方法的指针,每个表项指向一个具体的方法代码。如果这个类重写了父类中的某个方法,则对应表项指向新的代码实现处。从父类继承来的方法位于子类定义的方法的前面。
动态绑定语句的编译、运行原理:我们假设 Father ft=new Son(); ft.say(); Son继承自Father,重写了say()。
1:编译:我们知道,向上转型时,用父类引用执行子类对象,并可以用父类引用调用子类中重写了的同名方法。但是不能调用子类中新增的方法,为什么呢?
因为在代码的编译阶段,编译器通过 声明对象的类型(即引用本身的类型) 在方法区中该类型的方法表中查找匹配的方法(最佳匹配法:参数类型最接近的被调用),如果有则编译通过。(这里是根据声明的对象类型来查找的,所以此处是查找 Father类的方法表,而Father类方法表中是没有子类新增的方法的,所以不能调用。)
编译阶段是确保方法的存在性,保证程序能顺利、安全运行。
2:运行:我们又知道,ft.say()调用的是Son中的say(),这不就与上面说的,查找Father类的方法表的匹配方法矛盾了吗?不,这里就是动态绑定机制的真正体现。
上面编译阶段在 声明对象类型 的方法表中查找方法,只是为了安全地通过编译(也为了检验方法是否是存在的)。而在实际运行这条语句时,在执行 Father ft=new Son(); 这一句时创建了一个Son实例对象,然后在 ft.say() 调用方法时,JVM会把刚才的son对象压入操作数栈,用它来进行调用。而用实例对象进行方法调用的过程就是动态绑定:根据实例对象所属的类型去查找它的方法表,找到匹配的方法进行调用。我们知道,子类中如果重写了父类的方法,则方法表中同名表项会指向子类的方法代码;若无重写,则按照父类中的方法表顺序保存在子类方法表中。故此:动态绑定根据对象的类型的方法表查找方法是一定会匹配(因为编译时在父类方法表中以及查找并匹配成功了,说明方法是存在的。这也解释了为何向上转型时父类引用不能调用子类新增的方法:在父类方法表中必须先对这个方法的存在性进行检验,如果在运行时才检验就容易出危险——可能子类中也没有这个方法)。
四:区分
程序在JVM运行过程中,会把类的类型信息、static属性和方法、final常量等元数据加载到方法区,这些在类被加载时就已经知道,不需对象的创建就能访问的,就是静态绑定的内容;需要等对象创建出来,使用时根据堆中的实例对象的类型才进行取用的就是动态绑定的内容。
Java方法的静态绑定与动态绑定讲解(向上转型的运行机制详解)的更多相关文章
- Java : 多态表现:静态绑定与动态绑定(向上转型的运行机制)
本来想自己写写的,但是看到有人分析的可以说是很清晰了,故转过来. 原文地址:http://www.cnblogs.com/ygj0930/p/6554103.html 一:绑定 把一个方法与其所在的类 ...
- “全栈2019”Java第五十五章:方法的静态绑定与动态绑定
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...
- 【转】java的动态代理机制详解
java的动态代理机制详解 在学习Spring的时候,我们知道Spring主要有两大思想,一个是IoC,另一个就是AOP,对于IoC,依赖注入就不用多说了,而对于Spring的核心AOP来说,我们 ...
- java 深拷贝与浅拷贝机制详解
概要: 在Java中,拷贝分为深拷贝和浅拷贝两种.java在公共超类Object中实现了一种叫做clone的方法,这种方法clone出来的新对象为浅拷贝,而通过自己定义的clone方法为深拷贝. (一 ...
- 《手把手教你》系列技巧篇(四十四)-java+ selenium自动化测试-处理https 安全问题或者非信任站点-下篇(详解教程)
1.简介 这一篇宏哥主要介绍webdriver在IE.Chrome和Firefox三个浏览器上处理不信任证书的情况,我们知道,有些网站打开是弹窗,SSL证书不可信任,但是你可以点击高级选项,继续打 ...
- 《手把手教你》系列基础篇(八十)-java+ selenium自动化测试-框架设计基础-TestNG依赖测试-番外篇(详解教程)
1.简介 经过前边几篇知识点的介绍,今天宏哥就在实际测试中应用一下前边所学的依赖测试.这一篇主要介绍在TestNG中一个类中有多个测试方法的时候,多个测试方法的执行顺序或者依赖关系的问题.如果不用de ...
- 《手把手教你》系列基础篇(八十一)-java+ selenium自动化测试-框架设计基础-TestNG如何暂停执行一些case(详解教程)
1.简介 在实际测试过程中,我们经常会遇到这样的情况,开发由于某些原因导致一些模块进度延后,而你的自动化测试脚本已经提前完成,这样就会有部分模块测试,有部分模块不能进行测试.这就需要我们暂时不让一些t ...
- JAVA中的GC机制详解
优秀Java程序员必须了解的GC工作原理 一个优秀的Java程序员必须了解GC的工作原理.如何优化GC的性能.如何与GC进行有限的交互,因为有一些应用程序对性能要求较高,例如嵌入式系统.实时系统等,只 ...
- Java 反射 设计模式 动态代理机制详解 [ 转载 ]
Java 反射 设计模式 动态代理机制详解 [ 转载 ] @author 亦山 原文链接:http://blog.csdn.net/luanlouis/article/details/24589193 ...
随机推荐
- 图论++【洛谷p1744】特价采购商品&&【一本通1342】最短路径问题
(虽然题面不是很一样,但是其实是一个题qwq) [传送门] 算法标签: 利用Floyed的o(n3)算法: (讲白了就是暴算qwq) 从任意一条单边路径开始.所有两点之间的距离是边的权,或者无穷大,如 ...
- 基于Python——实现远程下载sftp文件(只下载.zip文件)
[背景]远程下载发布包等文件时,总是要使用WinSCP等工具登陆拖动.今天就介绍一种使用python下载文件到本地的方法. [代码实现] import paramiko # paramiko模块,基于 ...
- 『Python』__getattr__()特殊方法
self的认识 & __getattr__()特殊方法 将字典调用方式改为通过属性查询的一个小class, class Dict(dict): def __init__(self, **kw) ...
- 『计算机视觉』R-FCN:Object Detection via Region-based Fully Convolutional Networks
一.网络介绍 参考文章:R-FCN详解 论文地址:Object Detection via Region-based Fully Convolutional Networks R-FCN是Faster ...
- hdu5421Victor and String 两端加点的pam
题意:要求维护两端加点的字符串,以及查询本质回文串个数和所有回文串个数 题解:pam,两端加点过程详见ioi2017国家集训队论文,维护一个最长回文前缀和最长回文后缀即可,fail不用两个,能前后共用 ...
- ABAP基础一:ALV基础之ALV的整体结构
很久没摸ECC了,最近看到很多新人在捯饬ALV...中国就喜欢量产垃圾...培训,上岗...没有行业道德... 闲话不多说,开始正事: ALV很常见,在SAP非WEB的项目,没有不用的,它包含了报表和 ...
- 全面了解TCP/IP到HTTP
一.OSI参考模型 OSI(Open System Interconnect),即开放式系统互联.一般都叫OSI参考模型,是ISO(国际标准化组织)组织在1985年研究的网络互联模型.该体系结构标准定 ...
- MegaCli 简易使用介绍
查看帮助 MegaCli64 -h 适配卡配置 查看RAID控制器的数量 MegaCli64 -adpCount 查看所有raid卡详细信息 MegaCli64 -AdpAllInfo -aALL 查 ...
- 输入、输出与Mad Libs游戏
name1 = input('请输入一个名字:') name2 = input('再输入一个名字:') article = input('请输入一种物品:') print('{}掉进了{},{}去救她 ...
- Centos7部署kubernetes测试k8s应用(九)
1.创建一个deployment [root@linux-node1 ~]# kubectl run net-test --image=alpine --replicas=2 sleep 360000 ...