1、先通過一張圖片來看看局部變量表和操作數棧之間的操作關系:
2、實例:
0 iconst_1 1 istore_1 2 iload_1 3 iinc 1 by 1 6 istore_1 7 iload_1 8 iinc 1 by 1 11 istore_2 12 iload_1 13 iinc 1 by 1 16 iload_1 17 iload_1 18 iinc 1 by 1 21 imul 22 iadd 23 istore_3
所以,我們現在解釋一下上面的代碼。int i = 1;發生了兩個過程,iconst_1 是將 int 型的 1 推送至棧頂。istore_1 把棧頂的元素彈出,並賦值給局部變量表中位置為“1”的變量,此時指變量i。這兩句就相當於 int i = 1;
i = i++; 代碼解釋:iload_1 把局部變量表中位置為“1”的變量加載到棧頂,即把 i 的值加載到棧頂。iinc 1 by 1,將局部變量表中位置為“1”的 i 加 1,此時局部變量表中 i 的結果為 2。然后 istore_1 把棧頂的元素彈出,並賦值給局部變量表中位置為“1”的變量。所以 i 的值又被改為了 1。
int j = i++; 代碼解釋:iload_1 把局部變量表中位置為“1”的變量加載到棧頂,即把 i 的值加載到棧頂。iinc 1 by 1 將局部變量表中位置為“1”的 i 加 1,此時結果為 2,也就是局部變量表中 i 的結果為 2。istore_2 把棧頂的元素彈出並賦值給局部變量表中位置為“2”的 j。所以 j 是 1,但是 i 的值已經為 2。
int k = i + ++i * i++; 這個是最復雜的,我們直接看 JVM 指令即可。iload_1 把局部變量表中位置為“1”的變量加載到棧頂,即把 i 的值加載到棧頂,注意 i 的值此時是 2。iinc 1 by 1,i 自增,然后 i 就變成 3 了。接着兩個 iload_1、iload_1分別把局部變量 i 壓到棧了。所以棧中現在是 3、3、2。然后執行 iinc 1 by 1,i 又自增了,這時把局部變量表中的 i 就變成 4 了,注意這個 4 並未壓入棧。之后 imul 進行乘法計算,棧中的前兩個元素計算后是 9,之后執行 iadd 指令,也就是 9 + 2,結果為 11。最后 istore_3 把 11 從棧頂彈出,並賦值給 k,也就是局部變量表中位置為“3”的 k 的值是 11。