java方法的虚分派和方法表
java:方法的虚分派(virtual dispatch)和方法表(method table)
Java方法调用的虚分派
虚分配(Virtual Dispatch)
首先从字节码中对方法的调用说起。Java的bytecode中方法的调用实现分为四种指令:
invokevirtual为最常见的情况,包含virtual dispatch机制;
invokerspecial是作为对private和构造方法的调用,绕过了virtual dispatch;
invokeinterface的实现跟invokevirtual类似;
invokestatic是对静态方法的调用;
其中最复杂的要属invokevirtual指令,它涉及到了多态的特性,使用virtual dispatch做方法调用。
virtual dispatch机制会首先从receiver(被调用方法的对象)的类的实现中查找对应的方法,如果没找到,则去父类查找,直找到函数并实现调用,而不是依赖于引用的类型。
下面是一段有趣的代码。反映了virtual dispatch机制和一般的field访问的不同。

运行结果:

前两行输出中,对于Intro这个属性的访问,直接指向了父类中的变量,因为引用类型为父类。
第二行对于target()的方法调用,则是指向了子类中的方法,虽然引用类型也为父类,但这是虚分配的结果,虚分配不管引用类型的,只查被调用对象的类型·。
既然需分派机制是从被调用对象本身的类开始查找,那么对于一个覆盖了父类中某方法的子类的对象,是无法调用父类中那个被覆盖的方法的吗?
在虚分派机制中这确实是不可以的。但却可以通过invokespecial实现。如下代码:

func()就成功地调用了父类的方法target(),虽然target()已经被子类重写了。具体的调用细节,从字节码中可以看到:

其中使用了invokespecial指令,而不是施行需分派策略的invokevirtual指令。
方法表(Method Table)
介绍了虚分派,接下来介绍是它的一种实现方法—方法表。类似于C++虚函数表vtbl。
在有的JVM实现中,使用了方法表机制实现虚分派,而有时候,为了节省内存可能不采用方法表的实现。
不要被方法表这个名字迷惑,它并不是记录所有方法的表。它是为虚分派服务,不会记录用invokestatic调用的静态方法和用invokespecial调用的够着函数和私有方法。
JVM会在链接类的过程中,给类分配相应的方法表内存空间。每个类对应一个方法表。这些都是存在于method area区中的。这里与C++略有不同,C++中每个对象的第一个指针就是指向了相应的虚函数表。而Java中每个对象索引到对应的类,在对应的类数据中对应一个方法表。
一种方法表的实现如下:
父类的方法比子类的方法先得到解析,即父类的方法相对于子类的方法位于表的前列。
表中每项对应于一个方法,索引到实际方法的实际代码上。如果子类重写了父类中某个方法的代码,则该方法第一次出现的位置的索引更换到子类的实现代码上,而不会在方法表中出现新的项。
JVM运行时,当代码索引到一个方法时,是根据它在方法表中的偏移量来实现访问。(第一次执行到调用指令时,会执行解释,将符号索引替换为对应的直接索引)。
invokeinterface与invokevirtual的比较
当使用invokeinterface来调用方法时,由于不同的类可以实现同一interface,我们无法确定在某个类中的interface中的方法处在哪个位置。于是,也就无法解释CONSTANT_interfaceMethodref-info为直接索引,而必须每次都执行一次在methodtable中的搜索了。所以,在这种实现中,通过invokeinterface访问方法比通过invokevirtual访问明显慢很多。
java方法的虚分派和方法表的更多相关文章
- 通过字节码分析Java方法的静态分派与动态分派机制
在上一次[https://www.cnblogs.com/webor2006/p/9723289.html]中已经对Java方法的静态分派在字节码中的表现了,也就是方法重载其实是一种静态分派的体现,这 ...
- java内省机制及PropertyUtils使用方法
背景 一般情况下,在Java中你可以通过get方法轻松获取beans中的属性值.但是,当你事先不知道beans的类型或者将要访问或修改的属性名时,该怎么办?Java语言中提供了一些像java.bean ...
- Java中的equals和hashCode方法
本文转载自:Java中的equals和hashCode方法详解 Java中的equals方法和hashCode方法是Object中的,所以每个对象都是有这两个方法的,有时候我们需要实现特定需求,可能要 ...
- Java提高篇——equals()与hashCode()方法详解
java.lang.Object类中有两个非常重要的方法: 1 2 public boolean equals(Object obj) public int hashCode() Object类是类继 ...
- Java中各种(类、方法、属性)访问修饰符与修饰符的说明
类: 访问修饰符 修饰符 class 类名称 extends 父类名称 implement 接口名称 (访问修饰符与修饰符的位置可以互换) 访问修饰符 名称 说明 备注 public 可以被本项目的所 ...
- [原创]java WEB学习笔记79:Hibernate学习之路--- 四种对象的状态,session核心方法:save()方法,persist()方法,get() 和 load() 方法,update()方法,saveOrUpdate() 方法,merge() 方法,delete() 方法,evict(),hibernate 调用存储过程,hibernate 与 触发器协同工作
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
- Java 重写hashCode 方法和equals方法
package Container; import java.util.HashSet; import java.util.Iterator; /* Set 元素是无序的(存入和取出的顺序不一定一致) ...
- java中equals方法和hashcode方法的区别和联系,以及为什么要重写这两个方法,不重写会怎样
一.在Object类中的定义为:public native int hashCode();是一个本地方法,返回的对象的地址值.但是,同样的思路,在String等封装类中对此方法进行了重写.方法调用得到 ...
- Java中的equals和hashCode方法详解
Java中的equals和hashCode方法详解 转自 https://www.cnblogs.com/crazylqy/category/655181.html 参考:http://blog.c ...
随机推荐
- F5 SSLVPN 的安装问题
WIN10下安装SSLVPN问题 1.右击计算机 -->选择管理-->查看安装的插件是否显示感叹号 2.如果显示感叹号-->则进行更新驱动-->>手动选择-->网络 ...
- [App Store Connect帮助]六、测试 Beta 版本(3.2)管理测试员:邀请外部测试员
在您上传至少一个构建版本之后,您可以邀请外部测试员(您组织之外的人员)使用“TestFlight Beta 版测试”来测试您的 App.为了使您的构建版本可用于外部测试,请创建一个群组.添加构建版本, ...
- 使用Gitalk实现静态页面评论的功能
使用静态页面的理由 本人在Github上使用github.io部署了一个静态主页,地址是http://aopstudio.github.io,用于存放一些笔记文件.虽然静态页面功能少,自动化程度低,不 ...
- hdu 模拟 贪心 4550
卡片游戏 Time Limit: / MS (Java/Others) Memory Limit: / K (Java/Others) Total Submission(s): Accepted Su ...
- [转]c++中的string常用函数用法总结
标准c++中string类函数介绍 注意不是CString之所以抛弃char*的字符串而选用C++标准程序库中的string类,是因为他和前者比较起来,不必 担心内存是否足够.字符串长度等等,而且作为 ...
- Windows环境下使用Netsh命令快速切换IP配置
不同的内网环境需要使用不同的IP配置,频繁切换令人发狂,因此搜索了快速切换IP配置的方法. Netsh interface IP Set address "以太网" Static ...
- DateFormat 多线程问题
在写实时应用解析日志的时候,有如下代码: public class CalPvLogParse { private static SimpleDateFormat logTimeFormat = ne ...
- opencv 检测图片中圆形物体(解决乱线问题)
2018-03-0418:03:12 整体代码如下: def detect_circle_demo (image): # 降噪处理 dst = cv.pyrMeanShiftFiltering(ima ...
- 预测学习、深度生成式模型、DcGAN、应用案例、相关paper
我对GAN"生成对抗网络"(Generative Adversarial Networks)的看法: 前几天在公开课听了新加坡国立大学[机器学习与视觉实验室]负责人冯佳时博士在[硬 ...
- 三维CNN:收集一些最近的3d卷积网络PointNet++
PointNet++是在PointNet上做出了改进,考虑了点云局部特征提取,从而更好地进行点云分类和分割. 先简要说一下PointNet: PointNet,其本质就是一种网络结构,按一定的规则输入 ...