在 Java 中,final 賦予對象不可變性,從三個維度產生深遠影響:
class Circle {
static final double PI = 3.1415926; // 編譯期常量
final int radius = 5; // 實例常量
final int xPos, yPos; // blank final
public Circle(int x, int y) {
xPos = x; yPos = y; // 構造器中初始化
}
}
blank final 必須在構造器/靜態塊中初始化final 只保證引用不變,對象內容仍可修改class BaseClass {
public final void method() {} // 子類不可覆寫
}
class DerivedClass extends BaseClass {
// public final void method() {} // 編譯錯誤
}
注意:final 方法不一定內聯,內聯決策由 JIT 基於熱點分析動態決定,非 final 關鍵字強制。
public final class String
implements Serializable, Comparable<String>, CharSequence { ... }
三大核心原因:
匿名內部類只能訪問 final 或 effectively final 的局部變量。編譯器會在內部類構造器中複製變量值,方法棧幀銷毀後內部類仍持有副本。
// JDK 內部實踐:用數組繞過限制
final boolean[] result = {false};
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
try {
result[0] = InetAddress.getByName(h1).equals(InetAddress.getByName(h2));
} catch (Exception e) {}
return null;
});
return result[0];
| 類型 | 定義位置 | 訪問外部成員 | 靜態成員 |
|---|---|---|---|
| 靜態嵌套類 | 類內部 | 僅靜態成員 | 允許 |
| 成員內部類 | 類內部 | 所有成員 | 不允許 |
| 局部內部類 | 方法內部 | final/效果上 final 的局部變量 | 不允許 |
| 匿名內部類 | 表達式中 | 同局部類 | 僅常量 (final static) |
final 是 Java 實現不可變模式的基石。從 String 到並發工具類,不可變性簡化了推理、消除了同步開銷、釋放了編譯器優化潛力。掌握 final 的語義邊界與底層機制,是寫出健壯、高效 Java 代碼的關鍵。