Java 編譯器在處理 final 變量時會進行一項重要優化:將常量值直接內聯複製到所有引用它的類中。這項機制能提升應用執行速度,但也帶來一個隱患——當原始常量定義修改後,若未重新編譯依賴類,舊的常量值仍會被使用。
假設有兩個類 ClassA 和 ClassB:
public class ClassA {
static public final int PORT = 80;
}
public class ClassB {
public ClassB() {
download(ClassA.PORT);
}
private void download(int port) { ... }
}
編譯時,ClassB 中的 download(ClassA.PORT) 會被直接替換為 download(80)。若稍後將 ClassA 的常量改為 PORT = 8080 並重新編譯 ClassA,但未重新編譯 ClassB,則 ClassB 仍會使用舊值 80。
final 常量後,務必對所有引用該常量的類執行完整重新編譯。clean 與 rebuild,確保無殘留舊編譯產物。final 可避免此問題,但會失去編譯器優化帶來的效能提升。在效能敏感場景下,保留 final 並嚴格管理編譯流程更為推薦。理解這一機制有助於避免難以排查的運行時不一致問題,是 Java 開發者必備的基礎知識。