++操作的坑,細節爬坑

先看一道阿里雲大學Java基礎自測-初級難度的題

很顯然操作順序先乘2再加1,結果101。GAME OVER!

WTF!結果是100,執手相看結果,竟無語凝噎。

-------------------------------------華麗麗的分割線---------------------------------------------

看看它的背後究竟發生了什麼:
1、javac -- $ javac Test.java

             先將這段代碼編譯成class文件;

2、javap -- $ javap -v -c -l Test.class 

             JDK自帶的反解析工具(https://blog.csdn.net/w372426096/article/details/81664431 這篇文章詳細介紹了javap的命令)

然後就能看到下面這段執行過程

再來解讀一下這個過程,就只看main方法的部分

 大概說下上圖中的棧幀:每當線程調用一個Java方法時,JVM就會在該線程對應的棧中壓入一個幀,Java中的棧就是由很多棧幀組成的。棧幀由三部分組成:局部變量區、操作數棧、幀數據區。

bipush、istore_1:這兩步就是聲明一個數值爲50,並把它賦值給下標索引爲1的變量;

iload_1:將下標索引爲1的int變量的值壓入棧中;

iinc   1,1:這一步就是說明了++的值去哪了,將指定下標索引的int值+1,這一步的操作並不在棧中,而且有沒有賦值我也不清          楚,所以此時的變量值是50還是51?不過這並不影響結果;

iconst_2:將int型的數值2壓棧;

imul:棧中的數值相乘;

istore_1:將結果賦值給下標索引爲1的變量;

此時變量的值就是100,後面就是調用println方法了。

我勒個去,原來如此啊。。。

-------------------------------------------------------------------------------------------------------

那麼~ ++i 爲什麼會改變值呢?

public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=2, args_size=1
         0: bipush        50
         2: istore_1
         3: iinc          1, 1  //變量自增
         6: iload_1             //增加後的值入棧
         7: istore_1            //再回賦值給變量
         8: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
        11: iload_1
        12: invokevirtual #3                  // Method java/io/PrintStream.println:(I)V
        15: return
      LineNumberTable:
        line 7: 0
        line 8: 3
        line 10: 8
        line 12: 15

現在,你是否明白了呢

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章