我正在学习如何阅读Java字节码,这非常有趣。根据我的理解,每个堆栈帧都有自己的变量数组。那么,所有类型(int
或引用)是否共享同一个数组?
public class ByteTest {
private int thisField;
public ByteTest(int f){
thisField = f;
}
}
在此代码中,iload_1
表示0th
点中已有值,但f
显然是第一个 int
此代码块中的变量,除了this
是此堆栈中的第一个引用变量的事实。那么,所有类型共享同一个数组?我的推理是否正确?这是构造函数的字节码
/* L4 */
0 aload_0; /* this */
1 invokespecial 10; /* java.lang.Object() */
/* L5 */
4 aload_0; /* this */
5 iload_1; /* f */
6 putfield 13; /* .thisField */
/* L6 */
9 return;
答案 0 :(得分:4)
是的,你是对的。堆栈帧为所有类型共享一组局部变量。另请参阅JVM规范中的this section:
每个框架(第2.6节)包含一个称为局部变量的变量数组。帧的局部变量数组的长度在编译时确定,并以类或接口的二进制表示形式提供,同时提供与帧相关的方法的代码(§4.7.3)。
单个局部变量可以包含
boolean
,byte
,char
,short
,int
,float
,{的值{1}}或reference
。一对局部变量可以包含returnAddress
或long
类型的值。
答案 1 :(得分:2)
是的,所有类型共享相同的数组。想到它的最好方法是你有一个最多65535个插槽的数组,你可以存储你想要的任何变量(虽然long和double每个占用两个插槽)。您甚至可以在方法的不同部分中将多个不同类型的值存储在同一插槽中。加载类时,JVM会对字节码执行静态分析,以确保始终将值加载为与最初存储的值相同的值。
以下是有效的
iconst_0
istore_0
iload_0
aconst_null
astore_0
aload_0
但以下内容无效
iconst_0
istore_0
aload_0
请注意,Java字节码也是如此。 Dalvik字节码具有类似但不同的类型检查规则。例如,Dalvik中的常量是无类型的,移动指令也是如此,因此第二个示例的Dalvik等价物将通过验证。