JVM角度分析i 和 i的區別

2021-09-29 12:57:04 字數 1800 閱讀 7957

最近看jvm的一些相關知識,看到i++和++i的指令執行過程,知道的其實也沒啥難的,不知道的估計也說不出為什麼兩個賦值結果不一樣。跟大夥分享分享我的理解。
首先要知道虛擬機器棧是什麼?虛擬機器棧裡都有什麼?此知識點要掌握關於虛擬機器棧中的運算元棧(以下用操作棧代替)和區域性變數表(以下用區域性表代替),還有jvm的基本指令。下面會主要涉及到區域性表和操作棧還有jvm指令這塊的知識。網上一大堆我就不詳細說明了。
public

static

void

main

(string[

] args)

public

static

void

main

(string[

] args)

兩塊**很簡單,就乙個i++的賦值和++i的賦值。很顯然 **1的結果是0,**2的結果是1.為什麼呢?

主要是因為jvm的指令操作不一樣。

**一的jvm執行指令

**2的jvm執行指令

感覺兩個都差不多,區別在哪,區別就在與執行iinc這個指令後的操作。先一步步看

bipush 100: 意思就是將100 壓棧到運算元棧中。

istore_1 :將運算元棧中的棧頂元素(值)存到區域性變數表中的第乙個(index=1)位置,

iinc 1 by 1 :這個看外掛程式,有的地方寫的是 iinc 1,1

意思是將區域性表中的第乙個位置的變數按常量1增加。

第乙個位置1代表索引,第二個1表示常量。

重點來了

iload_1:從區域性表中的第乙個變數的值出棧到運算元棧中。

相當於從區域性表中讀了第乙個資料然後存到操作表中。可以這麼簡單的理解。

區別就在於

i++是直接將操作表中資料存到區域性表中。

而++i是先讀取的區域性表中的資料到操作棧,然後在從操作棧存到區域性表中。

為什麼這樣做?主要是因為iinc這個命令,這個命令是操作的是區域性表。

i++:

iinc 執行之前是 區域性表中變數值是100的而操作棧裡的值也是100.

但是執行完iinc命令後是區域性表中值變成101,而操作棧中的值依然是100;最後執行istore區域性表變100.

++i:

iinc執行之前是區域性表中變數值是100,而操作棧裡是空的。

iinc執行完後區域性表中是101,由於執行了iload操作棧也是101.最後執行了istore最終區域性表變101.

但是上面的**都是有 「=」 符號的。假如沒有「=」 符號會發生什麼。

當你不做任何賦值的時候++i和i++是沒有區別的。當賦值的時候才會存在區別。

i++和++i最終的區別其實就在於有沒有去讀區域性表中的變數的值。
小白第一次寫部落格,說的寫的不對的,有錯誤的請指出,一起**,盡快做修正,以免誤導別人。

感謝大家!!!

從jvm棧幀中區別i 和 i

有關jvm的一些詳細內容我就不在贅述,那麼到底i 和 i的區別體現在 呢?從位元組碼上來看,i 是iload,iinc,而 i是iinc,iload iload是從區域性變數表中載入int型別的資料到操作棧中 iinc是int變數的增值變化,是在區域性變數表中自增的 istore是將操作棧頂的int...

i和i 的區別

大家都應該知道i 和 i的區別,前者是先使用i的值,然後再增加1,而後者是先增加1然後再使用i的值。但是i 和 i那個更好呢?我們實現角度來看 前者是將i值加1後賦給i,然後返回i本身 而後者是先用個臨時變數儲存i值,然後將i值加1賦給i,然後返回臨時變數的值。內建資料型別他們的效率差不多,看他們的...

i 和 i的區別

當年上c 課的時候對於i 和 i的區別就稀里糊塗。後來沒注意也沒出過什麼問題。但是這個問題還是應該搞清楚。假如有乙個vector,值為 1,2,3,4,5,6,7 用以下程式輸出 i 0 while i 7 i 0 while i 7 cout beforei v i endl cout befor...