Java 中的自增運算符(++)看似簡單,但 i = i++ 與 i = ++i 的行為差異常讓開發者困惑。本文通過字節碼級分析揭示其內部機制,並對比 C/C++ 的不同行為。
public class Inc {
public static void main(String[] args) {
Inc inc = new Inc();
int i = 0;
inc.fermin(i);
i = i++;
System.out.println(i); // 輸出 0
}
void fermin(int i) {
i++;
}
}
結果:0(若為 C/C++ 則輸出 1)
Java 編譯器為表達式求值引入了臨時變量(操作數棧槽位),導致賦值與自增的順序固化:
i = i++ 等價於:
temp = i(保存舊值)i = i + 1(自增)i = temp(將舊值寫回,覆蓋自增結果)i = ++i 等價於:
i = i + 1(先自增)temp = i(保存新值)i = temp(寫回新值)i 的值(0)拷貝到臨時變量區(temp=0)。i 自增,值變為 1。i,最終 i 重置為 0。C/C++ 無額外臨時變量,所有操作在同一內存地址完成,故 i = i++ 結果為 1(未定義行為,編譯器實現不同)。
// 推薦寫法
i++;
int result = i; // 或直接使用 i
++i。Java 的 i = i++ 因引入臨時變量導致自增結果被覆蓋,最終值不變。理解 JVM 表達式求值機制有助於編寫無歧義、可維護的代碼。