Files
Hui-s-notebook/方法调用.md
2023-09-10 10:50:53 +08:00

1.8 KiB
Raw Permalink Blame History

解析

虚拟机支持以下方法调用字节码指令 invokestatic 调用静态方法 invokespecial 调用实例构造器方法 invokevirtual 调用所有虚方法 invokeinterface 调用接口方法,运行时确定一个实现该接口的对象 invokedynamic 现在运行时动态解析出调用点限定符所引用的方法,然后在执行该方法

分派

静态分派

静态类型和运行时类型 静态类型在编译期可知,而实际类型变化的结果在运行时才可确定 静态分派最典型应用为方法重载,静态分派发生在编译阶段,确定静态分派的动作实际上不由虚拟机执行 当方法传入的类型有匹配的类型时会使用该类型否则会使用该类型的父类的重载方法直到Object

动态分派

invokevirtual指令执行的第一步是在运行期确定接收者的实际类型并不是把常量池中方法的符号引用解析到直接引用上还会根据方法接收者的实际类型来选择方法版本 字段永远不参与多态,子类声明与父类同名的字段时,子类的字段会屏蔽父类的字段

单分派与多分派

Java的静态分派属于多分派动态分派属于单分派

虚拟机动态分派实现

基于执行性能的考虑运行时不会如此频繁地区反复搜索类型元数据一种基础而常见的优化手段是为类型在方法区中建立一个虚方法表Virtual Method Table使用虚方法表索引来代替元数据查找以提高性能 虚方法表中存放着各个方法的实际入口地址,如果某个方法在子类中没有被重写,那子类的虚方法表中的地址入口和父类相同方法的地址入口是一致的,都执行父类的实现入口,如果子类中重写了这个方法,子类虚方法表中的地址也会被提换位指向子类实现版本的入口地址