JVM调用指令

简介: JVM调用指令
五种指令

普通调用指令:

  • invokestatic:调用静态方法
  • invokespecial:调用私有实例方法、构造器,和父类的实例方法或构造器,以及所实现接口的默认方法
  • invokevirtual:调用所有虚方法(虚方法分派)
  • invokeinterface:调用接口方法

动态调用指令:

  • invokedynamic:动态解析出需要调用的方法
  • Java7 为了实现动态类型语言支持而引入了该指令,但是并没有提供直接生成 invokedynamic 指令的方法,需要借助 ASM 这种底层字节码工具来产生 invokedynamic 指令
  • Java8 的 lambda 表达式的出现,invokedynamic 指令在 Java 中才有了直接生成方式

指令对比:

  • 普通调用指令固化在虚拟机内部,方法的调用执行不可干预,根据方法的符号引用链接到具体的目标方法
  • 动态调用指令支持用户确定方法
  • invokestatic 和 invokespecial 指令调用的方法称为非虚方法,虚拟机能够直接识别具体的目标方法
  • invokevirtual 和 invokeinterface 指令调用的方法称为虚方法,虚拟机需要在执行过程中根据调用者的动态类型来确定目标方法

指令说明:

  • 如果虚拟机能够确定目标方法有且仅有一个,比如说目标方法被标记为 final,那么可以不通过动态绑定,直接确定目标方法
  • 普通成员方法是由 invokevirtual 调用,属于动态绑定,即支持多态

符号引用

在编译过程中,虚拟机并不知道目标方法的具体内存地址,Java 编译器会暂时用符号引用来表示该目标方法,这一符号引用包括目标方法所在的类或接口的名字,以及目标方法的方法名和方法描述符

  • 对于静态绑定的方法调用而言,实际引用是一个指向方法的指针
  • 对于需要动态绑定的方法调用而言,实际引用则是一个方法表的索引

符号引用存储在方法区常量池中,根据目标方法是否为接口方法,分为接口符号引用和非接口符号引用:

 Constant pool:
 ...
   #16 = InterfaceMethodref #27.#29  // 接口
 ...
   #22 = Methodref          #1.#33   // 非接口
 ...

对于非接口符号引用,假定该符号引用所指向的类为 C,则 Java 虚拟机会按照如下步骤进行查找:

  1. 在 C 中查找符合名字及描述符的方法
  2. 如果没有找到,在 C 的父类中继续搜索,直至 Object 类
  3. 如果没有找到,在 C 所直接实现或间接实现的接口中搜索,这一步搜索得到的目标方法必须是非私有、非静态的。如果有多个符合条件的目标方法,则任意返回其中一个

对于接口符号引用,假定该符号引用所指向的接口为 I,则 Java 虚拟机会按照如下步骤进行查找:

  1. 在 I 中查找符合名字及描述符的方法
  2. 如果没有找到,在 Object 类中的公有实例方法中搜索
  3. 如果没有找到,则在 I 的超接口中搜索,这一步的搜索结果的要求与非接口符号引用步骤 3 的要求一致
目录
相关文章
|
3天前
|
监控 Java Linux
Linux下JVM相关指令详解及案例介绍
Linux下JVM相关指令详解及案例介绍
13 1
|
2天前
|
存储 运维 Java
Java中的字节码与JVM指令集详解
Java中的字节码与JVM指令集详解
|
9天前
|
存储 Java 机器人
Java中的字节码与JVM指令集详解
Java中的字节码与JVM指令集详解
|
2月前
|
存储 Java 索引
深入浅出JVM(十)之字节码指令(下篇)
深入浅出JVM(十)之字节码指令(下篇)
|
2月前
|
存储 Java 索引
深入浅出JVM(九)之字节码指令(上篇)
深入浅出JVM(九)之字节码指令(上篇)
|
2月前
|
存储 Java 调度
JVM指令手册
JVM指令手册汇总
|
2月前
|
Java
|
2月前
|
存储 Java 编译器
深入理解JVM - 字节码指令
深入理解JVM - 字节码指令
72 0
|
9月前
|
Java 编译器
【面试题精讲】JVM-clinit指令
【面试题精讲】JVM-clinit指令
|
12月前
|
存储 Java 编译器
jvm之字节码指令集解读(上)
jvm之字节码指令集解读(上)