参考地址:https://www.zhihu.com/question/24747160
问:int a = 3; 首先它会在栈中创建一个变量为a的引用,然后查找有没有字面值为3的地址,没找到,就开辟一个存放3这个字面值的地址,然后将a指向3的地址?
是不是说要建立一个字面值为3的内存,再建立一个指向3的地址?就是要建立2个内存?
答:
栈深度为2 本地变量表为4(对象方法对this的引用 存储i和j需要的地址 存储Bar用的地址)
由于我代码中是写死的字面常量100000000 所以有个ldc命令去常量池里读了
public void foo() { int i = 100000000; int j = 1; Bar b = new Bar(); }
上面代码编译成class文件之后
public void foo(); flags: ACC_PUBLIC Code: stack=2, locals=4, args_size=1 0: ldc #15 // int 100000000 2: istore_1 3: iconst_1 4: istore_2 5: new #1 // class Bar 8: dup 9: invokespecial #16 // Method "<init>":()V 12: astore_3 13: return LineNumberTable: line 3: 0 line 4: 3 line 5: 5 line 6: 13 LocalVariableTable: Start Length Slot Name Signature 0 14 0 this LBar; 3 11 1 i I 5 9 2 j I 13 1 3 b LBar;
栈深度为2 本地变量表为4(对象方法对this的引用 存储i和j需要的地址 存储Bar用的地址)
由于我代码中是写死的字面常量100000000 所以有个ldc命令去常量池里读了
#15 = Integer 100000000
这个常量 然后调用store命令存入了本地变量表的第Name为1的位置
然后后边的int j = 1; 直接调用了iconst_1(这个1都没有存到类的常量池里..)获取了值为1的常量 然后存储到了Name为2的位置
然后Bar对象是引用类型 所以是LBar
例子并不全 你可以自己加一些代码 比如你加一个 int h = i + j;
你就会发现他通过iload命令读取加载变量表中指定位置的值到栈中 然后调用iadd自动从栈中弹出两个之前加载的int值进行计算 栈深度其实就是指他一次能加载多少变量到栈