1、先通過一張來看看區域性變數表和運算元棧之間的操作關係:
2、例項:
所以,我們現在解釋一下上面的**。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。
從jvm棧幀中區別i 和 i
有關jvm的一些詳細內容我就不在贅述,那麼到底i 和 i的區別體現在 呢?從位元組碼上來看,i 是iload,iinc,而 i是iinc,iload iload是從區域性變數表中載入int型別的資料到操作棧中 iinc是int變數的增值變化,是在區域性變數表中自增的 istore是將操作棧頂的int...
讀書筆記 區域性變數和棧幀
區域性變數 local variable 是指作用域和生命週期都侷限在所在函式或過程範圍內的變數,它是相對於全域性變數 global variable 而言的。編譯器在為區域性變數分配空間時通常有兩種做法 使用暫存器和使用棧。暫存器的訪問速度快,但數量和空間有限,所以像字串或陣列不適合分配在暫存器中...
讀書筆記 區域性變數和棧幀
區域性變數 local variable 是指作用域和生命週期都侷限在所在函式或過程範圍內的變數,它是相對於全域性變數 global variable 而言的。編譯器在為區域性變數分配空間時通常有兩種做法 使用暫存器和使用棧。暫存器的訪問速度快,但數量和空間有限,所以像字串或陣列不適合分配在暫存器中...