JVM字节码分析--invoke指令
一、方法调用的5个字节码指令
在对象实例初始化时,方法的调用会对应5种字节码指令
- invokestatic:用于调用静态方法
- invokespecial:用于调用私有实例方法、构造器,以及使用 super 关键字调用父类的实例方法或构造器,和所实现接口的默认方法
- invokevirtual:用于调用非私有实例方法
- invokeinterface:用于调用接口方法
- invokedynamic:用于调用动态方法
二、方法的静态绑定与动态绑定
静态绑定: 在编译时时能确定目标方法叫做静态绑定。(static修饰的方法、private方法),对应的是invokestatic 和 invokespecial 这两个指令。
动态绑定: 需要在运行时根据调用者的类型动态识别的叫动态绑定。(多态、public、protected方法),对应的是invokevirtual、invokeinterface和invokedynamic这三个指令。
三、invokestatic、invokevirtual 、invokespecial 、invokeinterface 和 invokedynamic 指令使用场景
invokestatic: 用来调用静态方法,即使用 static 关键字修饰的方法。 它要调用的方法在编译期间确定,运行期不会修改,属于静态绑定。它也是所有方法调用指令里面最快的。
例如:
String.valueOf(123)
invokespecial: 它是特殊的方法调用,包括实例构造方法、私有方法(private 修饰的方法)和父类方法(即 super 关键字调用的方法)。很明显明显,这些特殊的方法可以直接确定实际执行的方法的实现,与 invokestatic 一样,也属于静态绑定。
invokevirtual: 用来调用 public、protected、package 访问级别的方法。方法要根据对象类型不同动态选择不同的类,在编译期不确定,属于动态绑定。
例如:
public class Car {
public void printCarName() {
System.out.println("Car name from