深入理解Java虚拟机 第2版 周志明著(七)

第8章 虚拟机字节码执行引擎

8.1 方法调用
方法调用不等同于方法执行,方法调用的唯一任务是确定调用哪一个方法。Class文件的编译过程不包含传统编译中的连接步骤,一切方法调用在Class文件里面存储的都是符号引用,而不是方法在实际运行时内存布局中的入口地址。
8.1.1 解析调用
解析调用可以确定的方法主要包括静态方法,私有方法,实例构造器,父类方法4类,在类加载时候就会把符号引用解析为该方法的直接引用,这些方法称为非虚方法。(只要能被invokestatic和invokespecial指令调用的方法)
虽然final方法使用invokevirtual指令,但是也是非虚方法。

8.1.2 静态分派调用(重载)
Human man = new Man();把Human叫做静态类型,Man叫做实际类型。静态类型的变化仅仅在使用时发生,变量本身的静态类型不会被改变,并且最终的静态类型是在编译期可知的,而实际类型变化的结果在运行期才可确定。例如

//实际类型变化
Human man = new Man();
man = new new Woman();
//静态类型变化
sr.sayHello((Man) man);
sr.sayHello((Woman) man);

虚拟机(准确的说是编译器)在重载时是通过参数的静态类型而不是实际类型作为判定依据的。并且静态类型是编译期可知的,因此,在编译阶段,Javac编译器会根据参数的静态类型决定使用哪个重载版本。
所有依赖静态类型来定位方法执行版本的分派动作称为静态分派。,典型应用就是方法重载。
char>int>long>float>double>自动装箱Character>Serializable>父类>数组

8.1.3 动态分派调用(重写)
invokevirtual指令的运行时解析过程:

  1. 找到操作数栈顶的第一个元素所指向的对象的实际类型,记作C。(在运行期确定接收者的实际类型)
  2. 如果在类型C中找到与常量中的描述符合简单名称都相符的方法,则进行访问权限验证,通过则返回这个方法的直接引用,否则,异常。
  3. 否则,按照继承关系继续按2查找。
  4. 始终没有找到,异常。
    这个过程就是重写的本质。这种在运行期根据实际类型确定方法执行版本的分派过程称为动态分派。

8.1.4 单分派与多分派
方法的接收者与方法的参数统称为方法的宗量。根据分派基于多少种宗量可以将分派划分为单分派和多分派两种。

  • 单分派:根据一个宗量对目标方法进行选择。
  • 多分派:根据多于一个宗量对目标方法进行选择。
    Java语言是一门静态多分派,动态单分派的语言。

8.2 动态类型语言支持(invokedynamic)
动态类型语言:关键特征是它的类型检查的主题过程是在运行期而不是编译器。
由于invokedynamic指令所面向的使用者并非java语言,而是其他Java虚拟机之上的动态语言,所以什么时候用到什么时候在研究吧。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值