參考地址: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值進行計算 棧深度其實就是指他一次能加載多少變量到棧