在JVM中,将符号引用转换为调用方法的直接引用与方法的绑定机制有关。

静态链接:

当一个字节码文件被装载进JVM内部时,如果被调用的目标方法在编译期可知,且运行期间保持不变时,调用方法的符号引用转换为直接引用的过程叫做静态链接。

动态链接:

如果被调用的方法在编译期无法被确定下来,只能够在程序运行期将调用方法的符号引用转换为直接引用,由于这种引用转换过程具备动态性,因此被称之为动态链接。

早期绑定:

早期绑定就是指被调用的目标方法如果在编译期可知,且运行期间保持不变时,即可将这个方法与所属的类型进行绑定。

晚期绑定:

如果被调用的方法在编译期无法被确定下来,只能够在程序运行期间根据实际的类型绑定相关的方法。

晚期绑定是多态特性的本质。

非虚方法:

如果方法在编译期就确定了具体的调用版本,在运行时不可变,就是非虚方法。

静态方法,私有方法,final方法,实例构造器,父类方法都是非虚方法。其他方法是虚方法。

JVM虚拟机栈:方法的调用_java

 关于invokedynamic指令:

JVM虚拟机栈:方法的调用_虚方法_02

 动态类型语言和静态类型语言:

两者区别在于对类型的检查在编译器还是在运行期,满足前者就是静态类型语言,反之就是动态类型语言。

java中方法重写的本质:

1、找到操作数栈顶的第一个元素所执行的对象的实际类型,记作C。

2、如果在过程结束:如果在C中找到符合的方法,就进行权限校验,如果通过则返回这个方法的直接引用,否则返回java.lang.IllegalAccessError异常(没有权限访问)。

3、否则,按照继承关系从下往上依次对C的各个父类进行第2步的搜索和验证过程

4、如果始终没有找到合适的方法,则抛出java.lang.AbstractMethodError异常。

虚方法表:

在面向对象的编程中,会很频繁的使用到动态分派,如果在每次动态分派的过程中都要重新在类的方法元数据中搜索合适的目标的话可能影响到执行效率。因此,为了提高性能,JVM采用在类的方法区建立一个虚方法表,使用索引表来代替查找。

每个类都有一个虚方法表,表中存放着各个方法的实际入口。

JVM虚拟机栈:方法的调用_虚方法_03