目录
一.什么是动态链接:
- 动态链接也可称为指向运行时常量池的方法引用
- 每一个栈帧内部都包含一个指向运行时常量池中该线程所属方法的引用。
- 应用的目的就是为了支持当前方法的代码能实现动态链接。
- 在java源文件被编译到字节码文件时,所有的变量和方法引用都作为符号引用保存在class文件的常量池里。
- 描述一个方法调用另外的其他方法时,就是通过常量池中指向方法的符号引用来表示的,那么,动态链接的作用就是为了将这些符号引用转换为调用方法的直接引用。
二.两种链接方式:
1.静态链接:
当一个字节码文件被装载进jvm内部时,如果被调用的目标方法在编译期可知,且运行期保持不变。为静态链接。
2.动态链接:
如果被调用的方法在编译期无法被确定下来,也就是说,只能够在程序运行期间调用方法的符号引用转换为直接引用,由于这种引用转换过程具备动态性,因此也就被称之为动态链接。
三.对应的方法的绑定机制:
1.早期绑定:
指被调用的目标方法如果在编译期可知,且运行期保持不变时,即可将这个方法与所属的类型进行绑定,这样一来,由于明确了被调用的目标方法究竟是哪一个,因此也就可以使用静态链接的方式将符号转换为直接引用。
2.晚期绑定:
如果被调用的方法在编译期无法确定下来,只能够在程序运行期根据实际的类型绑定相关的方法,这种绑定方式也就被称为晚期绑定。
四.虚方法与非虚方法:
1.非虚方法:
- 如果方法在编译期就确定了具体的调用版本,这个版本在运行时是不可变的,这样的方法称为非虚方法。
- 静态方法、私有方法、final方法、实例构造器、父类方法都是非虚方法。
2.虚方法:
在编译期间无法确定的方法。
五.虚拟机中提供的几条方法调用指令:
A.普通调用指令
1.invokestatic:
调用静态方法,解析阶段确定唯一方法版本
2.invokespecial:
调用< init >方法,私有哦父类方法,解析阶段确定唯一方法版本。
3.invokevirtual:
调用所有虚方法
4.invokeinterface:
调用接口方法
B.动态调用指令:
1.invokedynamic:
动态解析出需要调用的方法,然后执行。
注:前四条指令固化在虚拟机内部,方法的调用执行不可人为干预,而invokedynamic执行则支持用户确定方法版本。其中,invokestatic指令和invokespecial指令调用的方法称为非虚方法,其余的(final修饰方法外)称为虚方法。