一点解释
局部变量数组的大小在编译时确定,取决于局部变量和形式方法参数的数量和大小。操作数堆栈是一个 LIFO 堆栈,用于推送和弹出值。它的大小也是在编译时确定的。某些操作码指令将值压入操作数堆栈;其他人从堆栈中获取操作数,操作它们,然后推送结果。操作数栈也用于接收方法的返回值。
public String getBar(){
return bar;
}
public java.lang.String getBar();
Code:
0: aload_0
1: getfield #2; //Field bar:Ljava/lang/String;
4: areturn
上述方法的字节码由三个操作码指令组成。第一个操作码 aload_0 将值从局部变量表的索引 0 压入操作数堆栈。this 引用始终存储在构造函数和实例方法的局部变量表的位置 0 处。下一个操作码指令 getfield 用于从对象中获取字段。最后一条指令 areturn 从方法返回一个引用。
每个方法都有一个对应的字节码数组。使用十六进制编辑器查看 .class 文件,您会在字节码数组中看到以下值:
也就是说,getBar 方法的字节码是 2A B4 00 02 B0。代码2A对应aload_0指令,B0对应areturn。该方法的字节码有 3 条指令,但字节数组包含 5 个元素,这可能看起来很奇怪。这是因为 getfield (B4) 需要提供 2 个参数 (00 02),并且这些参数在数组中占据位置 2 和 3,因此数组大小为 5,并且 areturn 指令移动到位置 4。
资源
Java 字节码指令列表