輸出結果是多少呢?自己思考後繼續往下看效果更好哦
..................................
......................................
正確答案是 0
如果能完全想明白,可以結束往下閱讀了。如果有疑惑,請繼續讀下去
我剛看到這道題,給的答案也是 1,因為我以往的理解是 i++ 是先賦值,然後再進行 ++ 操作,在賦值時,i 確實為 0,但 i 應該完成了自增操作,輸出的 i 應該為 1 呀,自己也驗證了一下,的確是 0。想不明白那就看看字節碼吧,也許從中能找到答案
先通過 javac AddTest.java 生成 AddTest.class 文件,然後通過 javap -v AddTest.class 查看具體的字節碼(只截取了部分)
首先說明左邊的數字序號表示字節碼的偏移量(偏移量和前面的字節碼長度有關),即當前字節碼所在的位置,很像行號,但不是行號
下面我們用圖解的方式分析下主要步驟
通過圖解我們發現操作數棧中的 0 把局部變量表 1 位置的 1 覆蓋了,所以最後輸出的結果是 0
指令說明
xconst_n (x為 i 表示整數,l 表示長整數,f 表示浮點數,d 表示雙精度浮點數,a 表示對象引用;n 為 0~5):常量入棧指令,代表將 n 壓入棧
xload_n(x 取值和 const 一樣,n 為 0~3):局部變量壓棧指令,將第n個局部變量壓入操作數棧
xstore_n(x 取值和 const一樣,n 為 0~3):出棧裝入局部變量表指令,從操作數棧中彈出,賦值給局部變量 n
iinc arg1,arg2:對給定的局部變量做自增操作。執行過程中不需要修改操作數棧。接收兩個操作數,第一個為局部變量表的位置,第二個為累加數
++i 呢?
說完了 i++ 就不能落下它的好兄弟 ++i
這個結果我想大家都能答對,輸出 1,但是我還是想把 ++i 的字節碼打出來,然後和 i++ 的進行對比
字節碼圖解如下所示
i++ 與 ++i 對比
我們把這兩個圖放在一起對比看下
反思
為何一道簡單的 i++ 的輸出問題,我都能弄錯?追根是因為對字節碼底層的不瞭解,雖然我們通過字節碼和畫圖分析出了原因,但這並不夠,最好做到看到代碼,對應的字節碼就映射到腦中。說實話,對我來說挺難的。需要不斷練習。懂了字節碼會對 Java 中更多底層的知識不止知其然,更知其所以然。
思考題
switch-case 是如何支持 String 類型的?
try-catch-finally 中 finally 裡面的代碼為何一定會執行?
————————————————
原文鏈接:https://blog.csdn.net/dam454450872/article/details/103231844
閱讀更多 IT知識課堂 的文章