| 關鍵字 | 類型 | 核心作用 |
|---|---|---|
| final | 修飾符 | 限制繼承、重寫、賦值;構建不可變對象 |
| finally | 異常處理塊 | 保證資源釋放代碼必執行 |
| finalize | Object 方法 | 垃圾回收前清理非 Java 資源(已棄用) |
public final class ImmutableClass {
// 無法被繼承,所有方法隱式 final
}
注意:final 類不能同時被 abstract 修飾,因為抽象類旨在被繼承。
public class Parent {
public final void doSomething() { /* 子類不可覆蓋 */ }
}
私有方法隱式 final,子類無法覆蓋(只能定義同名新方法)。
// 基本類型:值不可變
final int MAX_SIZE = 100;
// 引用類型:引用不可變,但對象內部狀態可變
final List<String> list = new ArrayList<>();
list.add("Hello"); // 合法
// list = new ArrayList<>(); // 編譯錯誤:引用不可重新賦值
錯誤觀點:「final 變量只能在聲明處或構造函數中初始化,二選一」
正確規則:final 變量必須在構造完成前顯式初始化一次,具體位置靈活:
{ ... }static { ... }(僅靜態 final 變量)public class FinalInitDemo {
final int a = 10; // 1. 聲明處
final int b; // 2. 必須在構造器/初始化塊賦值
final int c; // 3. 實例初始化塊
{ c = 30; }
static final int d; // 4. 靜態初始化塊
static { d = 40; }
public FinalInitDemo() {
b = 20; // 構造函數賦值
}
}
常見誤區:「防止方法內修改參數影響外部變量」
事實:Java 傳值調用,基本類型傳值副本,引用類型傳引用副本。方法內重新賦值參數(param = new Obj())絕不影響外部實參;修改對象內部狀態(param.setField())無論是否 final 都會影響外部。
真實用途:允許匿名內部類/Lambda 捕獲該參數。編譯器要求被捕獲的局部變量/參數實際最終不變,final 保證了生命週期延長至內部類實例存活期間。
public void executeTask(final String config) {
new Thread(() -> {
// config 被捕獲,必須 final 或 effectively final
System.out.println("Config: " + config);
}).start();
}
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try {
conn = getConnection();
try {
stmt = conn.createStatement();
try {
rs = stmt.executeQuery(sql);
// 處理結果集
} finally {
if (rs != null) rs.close();
}
} finally {
if (stmt != null) stmt.close();
}
} finally {
if (conn != null) conn.close();
}
try (Connection conn = getConnection();
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql)) {
// 自動按相反順序調用 close()
} catch (SQLException e) {
// 異常處理
}
優勢:代碼簡潔、自動處理異常抑制、編譯器生成正確的資源釋放邏輯。
Object,簽名 protected void finalize() throws Throwable@Deprecated(since="9", forRemoval=true)| 場景 | 推薦方案 |
|---|---|
| 文件/網絡/數據庫連接 | Try-with-resources / 顯式 close() |
| 原生內存/Off-heap 資源 | Cleaner / PhantomReference (Java 9+) |
| 緩存/觀察者模式註冊 | 弱引用 WeakReference + ReferenceQueue |
| 維度 | final | finally | finalize |
|---|---|---|---|
| 語法角色 | 修飾符 | 代碼塊 | 方法 |
| 編譯期檢查 | 強制 | 強制(配合 try) | 無 |
| 運行期保證 | 引用不變 | 代碼必執行 | 無保證 |
| 主要用途 | 不可變性、線程安全 | 資源釋放 | 歷史遺留清理(棄用) |