許多 Java 初學者會困惑:i++ 和 ++i 的運算結果暫存在哪裡?是存在堆疊(Stack)還是堆積(Heap)?這其實觸及了 Java 記憶體模型的核心觀念。
int i)儲存在執行緒私有的堆疊幀中。new Object())儲存在共享的堆積中。i++ 的舊值、++i 的新值)屬於運算元堆疊(Operand Stack)的一部分,同樣位於當前幀中,不會落入堆積。編譯後的字節碼最能說明一切(以 int i = 0; 為例):
| 原始碼 | 關鍵位元碼指令 | 說明 |
|---|---|---|
i++ | iload_1 → iinc 1 1 → istore_1 | 先載入舊值到操作數堆疊,再自增,最後存回區域變數表 |
++i | iinc 1 1 → iload_1 | 直接自增區域變數,再載入新值到操作數堆疊 |
兩者的中間數值都只存在於當前幀的操作數堆疊,屬於極短暫的臨時值,方法返回即銷毀,完全不涉及堆積記憶體。
Integer i = 0; i++ 會觸發自動裝箱/拆箱,產生新的 Integer 物件於堆積,但這是包裝類別特有行為,非基本型別 int。想徹底搞懂 JVM 記憶體結構,推薦閱讀《深入理解 Java 虛擬機器》第 2 章「Java 記憶體區域與記憶體溢出異常」,或參考 果殼網這篇圖解文章,裡面有動態示意圖幫助建立直觀認知。
下次面試官再問「i++ 存在哪」,你可以自信回答:基本型別區域變數與運算中間值全在執行緒堆疊,唯有 new 出來的物件才在堆積。