位元組碼指令分析 ++i 和 i++

TreeCode發表於2020-10-19

源起:

最近在學jvm,碰到一道分析題,用位元組碼指令分析++i 和 i++的區別,相信大家對++i 和 i++的區別應該非常熟悉,但是具體為什麼會這樣可能還是一知半解,這篇分享和大家共同解惑。

程式碼:

程式碼非常簡單,這裡就只分析question02了,下面的內容如果不熟悉區域性變數表和運算元棧的可能不太容易理解。

    public void test03(){
        // question01
        int i1 = 10;
        i1++;
        int i2 = 10;
        ++i2;


        //question02
        int i3 = 10;
        int i4 = i3++;
        int i5 = 10;
        int i6 = ++i5;


        //question03
        int i7 = 10;
        i7 = i7++;

        int i8 = 10;
        i8 = ++i8;


        //question04
        int i9 = 10;

        int i11 = 10;

        int i10 = i9++ + ++i9;
        int i12 = ++i11 + i11++;
        
    }

位元組碼:
我用的是jclasslib外掛看的位元組碼,但是不知道為啥,裡面字型很小,如果朋友們知道怎麼處理,請務必分享給我,十分感謝!!!
分析第7到第11行:
首先 bipush 把i3壓入運算元棧,然後 istore_3 把這個值存到區域性變數表,到這裡,int i3 = 10;這句話就執行完畢了,接下來重點來了, iload_3 然後iinc 3 by 1 表示先把i3取到了運算元棧,然後在區域性變數表中自增一,最後istore 4 把運算元棧中的i3存入區域性變數表,因為自增行為繞過了運算元棧,所以istore 4時存的值為10,而不是自增後的值。
分析第12到16行
12,13行和第7,8行的操作是一樣的,不再贅述,重點是第14-16行,14:iload_5 然後iinc 3 by 1 :先在區域性變數表中自增,然後iload 5,把自增後的值讀到運算元棧中,最後istore 6 存到一個新的區域性變數中,這樣就完成了先自增再儲存。我相信這裡能理解的話,下面的也沒問題了,大家可以自己去看看。
在這裡插入圖片描述

相關文章