Java 字节码可以划分为很多种类型,如加载常量指令,操作数栈专用指令,局部变量区访问指令,Java 相关指令,方法调用指令,数组相关指令,控制流指令,以及计算相关指令。
Chapter 6. The Java Virtual Machine Instruction Set (oracle.com)
具备高层语义的指令
new
后跟目标类,生成该类的未初始化的对象)
instanceof
后跟目标类,判断栈顶元素是否为目标类 / 接口的实例。是则压入 1,否则压入 0
checkcast
后跟目标类,判断栈顶元素是否为目标类 / 接口的实例。如果不是便抛出异常
athrow
将栈顶异常抛出
monitorenter
为栈顶对象加锁
monitorexit
为栈顶对象解锁
静态字段访问指令
getstatic
putstatic
实例字段访问指令
getfield
putfield
以 putfield 为例,在上图中,它会把值 v 存储至对象 obj 的目标字段之中。
方法调用指令
invokestatic
invokespecial
invokevirtual
invokeinterface
invokedynamic
public int neg(int i) {
return -i;
}
public int foo(int i) {
return neg(neg(i));
}
// foo方法对应的字节码如下:foo方法对应的字节码如下:
public int foo(int i);
0 aload_0 [this]
1 aload_0 [this]
2 iload_1 [i]
3 invokevirtual FooTest.neg(int) : int [25]
6 invokevirtual FooTest.neg(int) : int [25]
9 ireturn
以上面这段代码为例,当调用 foo(2) 时,每条指令执行前后局部变量数组空间以及操作数栈的分布如下所示
数组访问指令表
控制流指令
包括无条件跳转 goto,条件跳转指令,tableswitch 和 lookupswtich(前者针对密集的 cases,后者针对稀疏的 cases),返回指令,以及被废弃的 jsr,ret 指令。其中返回指令是区分类型的。例如,返回 int 值的指令为 ireturn。