final 是 Java 的保留字,核心語意是「不可變更」。依修飾目標不同,具體行為有所差異。本文系統整理四大使用場景與底層原理。
| 分類 | 初始化時機 | 適用型別 | 不可變內容 |
|---|---|---|---|
| 編譯期常量 | 宣告時必須賦值 | 基本型別 + String | 值本身 |
| 執行期常量 | 宣告時或建構子中賦值(實例變數);宣告時賦值(區域變數) | 基本型別、引用型別 | 基本型別:值;引用型別:引用指向(物件內容仍可修改) |
// 編譯期常量 static final double PI = 3.14159; // 執行期常量(引用型別) final Listlist = new ArrayList<>(); list.add("A"); // ✅ 允許修改物件內容 // list = new ArrayList<>(); // ❌ 編譯錯誤:不可改變引用指向
final 方法無法被子類別覆寫,保證演算法不被竄改。final 語意(子類別不可見,自然無法覆寫)。final 方法,現代 JIT 編譯器已自動優化,不需為效能刻意加 final。final class 無法被繼承(如 String, Integer, LocalDate)。final,但欄位不自動成為 final。public void process(final String input) {
// input = "new"; // ❌ 編譯錯誤
System.out.println(input.length());
}
核心用途:匿名內部類別/Lambda 捕獲區域變數。Java 要求被捕獲的區域變數實際上不可變(effective final),final 明確保證此點,避免外部修改導致內部類別看到不一致的值。
void startTask(final int count) { // Java 8+ 可省略 final,但變數必須 effective final
new Thread(() -> {
for (int i = 0; i < count; i++) { // 捕獲 count
System.out.println(i);
}
}).start();
}
final 禁止外部修改,消除此風險。final 關鍵字(effective final)。| 修飾目標 | 核心限制 | 典型場景 |
|---|---|---|
| 類別 | 不可被繼承 | 不可變類別、工具類、安全類 |
| 方法 | 不可被覆寫 | 模板方法固定步驟、效能敏感熱點 |
| 實例/靜態變數 | 引用不可變更(基本型別值不可變) | 常量定義、依賴注入欄位、集合引用固定 |
| 區域變數/參數 | 不可重新賦值 | Lambda/匿名類別捕獲、防止誤改參數 |