关于JVM中的分派
来源:互联网 发布:插画师卤猫 知乎 编辑:程序博客网 时间:2024/05/29 23:48
前提
首先在此明确几个定义。
(1)
对于:
ClassA instance = new ClassA();instance.doing(Object arg);
instance是调用者,doing是ClassA的方法,Object arg是doing的参数。
(2)
class Father{}public class Son extends Father{ public static void main{ Father instance = new Son(); }}
【静态类型】又叫外观类型。上面的instance的静态类型就是Father。(注意:静态类型不是指Java中的静态成员的静态)
【动态类型】上面instance的实际类型就是Son
分派
可以参考《深入理解Java虚拟机:JVM高级特性与最佳实践》8.3.1与8.3.2
在此我只写出结论:
- 静态分派一般都发生在编译阶段,它同时需要考察调用者的静态类型和参数的静态类型,因此也是多分派
- 动态分派一般发生在运行时,它仅考察调用者的实际类型,因此也是单分派
实际上任何一条方法调用语句,都要经过编译期的静态分派和运行时的动态分派。
重载与重写的实现
- 重载的实现有赖于静态分派中对参数的静态类型的考察(调用者类型都是一样的)
- 重写的实现有赖于动态分派
指令与分派
我们知道有四个方法调用指令:
invokestatic:调用静态方法
invokespecial:调用实例构造器方法、私有方法合父类方法
invokevirtual:调用所有的虚方法
invokeinterface:调用接口方法
(参考《深入理解Java虚拟机:JVM高级特性与最佳实践》8.3.1,p207)
下面问个问题:
public class Dispatch { static class QQ{} static class _360{} static public class Father{ static public void hardChoice(QQ arg){ System.out.println("father choose qq"); } } static public class Son extends Father{ static public void hardChoice(QQ arg){ System.out.println("son choose qq"); } } public static void main(String[] args){ Father son = new Son(); son.hardChoice(new QQ()); }}
它的输出是什么?这个例子我是根据《深入理解Java虚拟机:JVM高级特性与最佳实践》p218,代码8-10改写的。
- 首先我要跟你说明它没有语法错误,Father的静态方法hardChoice看起来好像是在Son中被重写了,实际上不是。准确地讲,叫“不可重写的继承”,就是说Son中可以调用继承来的Father.hardChoice,但是在Son中再写一个静态的hardChoice实际上不是重写而是另写。
- 其次我要告诉你答案:father choose qq。那么为什么呢?
我们根据上面的知识,首先编译器将语句son.hardChoice(new QQ());
进行了静态分派:son的静态类型是Father,方法参数的静态类型为QQ,方法名为hardChoice是静态方法,因此指令为invokestatic Father.hardChoice(QQ);然后在运行时,JVM在执行invokestatic时并不进行动态分派,于是便执行了Father.hardChoice方法。
JVM在执行指令invokestatic 、invokespecial以及final的invokevirtual,都不会进行动态分派,也正是这个原因才导致可以在类加载阶段就将其操作数(符号引用)解析为该方法的直接引用。(《深入理解Java虚拟机:JVM高级特性与最佳实践》p208)
因此我们明白,静态分派与指令没有什么关系;但是指令却决定了JVM是否进行动态分派。
- 关于JVM中的分派
- JVM方法分派
- JVM解析与分派
- 【JVM】静态分派和动态分派
- JVM方法分派:静态多分派、动态单分派
- 深入理解jvm之分派
- JVM之方法调用-分派
- 深入理解JVM九---分派
- 关于任务的分派
- Java中的静态分派与动态分派
- java中的静态分派与动态分派
- Java中的方法分派
- 深入理解JVM之七:静态分派与动态分派
- 深入理解JVM之七:静态分派与动态分派
- 深入理解JVM之七:静态分派与动态分派
- 【深入理解JVM】:解析与分派
- JVM 方法调用之动态分派
- JVM 方法调用之动态分派
- RedHat机器opencv安装
- 实现自动构建编译javaweb项目并发布到N台服务器
- 数字签名和数字证书的学习总结
- Android-25种开源炫酷动画框架
- 用happen-before规则重新审视DCL
- 关于JVM中的分派
- synchronized 与 Lock区别
- 抛个关于nginx下载文件乱码的问题
- 2016 天梯赛初赛 排座位(并查集)
- 请求参数获取与编码问题
- 开源一个小APP(明天计划),欢迎交流Android架构
- 分布式事务示例
- TV电视直播源
- JS跨域设置和取Cookie(二)