『Java 語法基礎』final、finalize 和 finally 的不同之處

BNTang發表於2024-03-18

final

final 是一個修飾符,是 Java 程式語言中的一個關鍵字,可以用來修飾變數、方法、以及類。使用 final 的效果是不同的,取決於它修飾的物件型別。下面我會分別解釋 final 修飾變數、方法和類時的效果。

final 修飾變數

final 修飾一個變數時,這個變數就變成了一個常量,也就是說它的值只能被賦值一次,一旦賦值之後就不能被修改了。如果嘗試修改 final 變數的值,編譯器會報錯。

final int number = 10; // 初始化 final 變數
// number = 15; // 編譯錯誤,不能修改 final 變數的值

final 修飾方法

final 修飾一個類的方法時,這個方法不能被子類覆蓋或重寫。這意味著子類不能提供一個具有相同名稱和引數型別的方法。

class Parent {
    final void show() {
        System.out.println("這是一個 final 方法。");
    }
}

class Child extends Parent {
    // 編譯錯誤,不能覆蓋 final 方法
    // void show() {
    //     System.out.println("嘗試覆蓋 final 方法。");
    // }
}

final 修飾類

final 修飾一個類時,表示這個類不能被繼承。換句話說,沒有其他類能夠繼承 final 類。

final class FinalClass {
    // 類的定義
}

// 編譯錯誤,不能繼承 final 類
// class SubClass extends FinalClass {
// }

finalize

finalize() 方法在 Java 中是與物件生命週期關聯的一個概念。當一個物件不再有任何的引用指向它,也就是說,這個物件不再被程式中的其他部分所需要時,Java 虛擬機器(JVM)的垃圾收集器(GC)可能會考慮將其回收以釋放記憶體資源。在垃圾收集器決定回收物件之前,finalize() 方法會被呼叫,給予了這個物件一個機會來進行清理工作,比如關閉開啟的資源等。

然而,finalize() 方法存在幾個問題:

  1. 不確定性:finalize() 方法被呼叫的具體時間是不確定的。垃圾收集器執行的時間取決於多種因素,包括 JVM 的記憶體使用情況、垃圾收集演算法等。這意味著,從物件不再有引用到 finalize() 方法被呼叫之間的時間可能非常長,甚至可能永遠不會被呼叫。
  2. 效能問題:由於 finalize() 執行不確定,且可能影響垃圾收集的效率,過度依賴 finalize() 方法可能會導致效能問題,例如延遲物件記憶體的回收,或導致記憶體洩漏。
  3. 資源釋放:如果你在 finalize() 方法中處理類似於檔案關閉等操作,可能會導致資源無法及時釋放。如果你的應用程式開啟了大量檔案且依賴於 finalize() 方法來關閉這些檔案,可能會導致資源耗盡,因為垃圾收集器沒有及時呼叫 finalize() 方法。

因此,通常的最佳實踐是避免使用 finalize() 方法來清理資源。相反,推薦使用 try-with-resources 語句或者顯式的清理方法,例如,在你控制資源的程式碼塊中使用 try-catch-finally 來確保資源始終得到適當的釋放。

簡而言之,finalize() 方法可以看作是在物件生命週期結束前的 “最後通牒”,雖然你可以在這裡做一些清理工作,但它的執行是不可預測的,並且可能會給程式帶來更多問題,因此不建議依賴它來釋放資源或做其他關鍵操作。

finally

finally 是一個關鍵字,與 try 和 catch 一起用於異常的處理。finally 塊一定會被執行,無論在 try 塊中是否有發生異常。

想象一下,你在遊樂場玩拋球遊戲。try 塊就像是你向籃筐投球的嘗試,如果球進了籃筐,那就意味著沒有發生錯誤,你的程式碼執行正常。而如果球沒有進籃筐,這就好比發生了異常,這時候 catch 塊就會介入,像是遊戲工作人員過來告訴你什麼出了問題,並給你另一次機會。

現在,打個比方,無論你是否成功將球投入籃筐(即無論 try 塊中的程式碼是否成功執行),你都必須將球還給工作人員,這個動作就像是 finally 塊。finally 塊確保了無論之前發生了什麼,一些必須進行的清理工作(比如歸還球)都會被執行。這表示即便在 try 塊中程式碼順利執行或 catch 塊捕獲到異常後執行相應的錯誤處理程式碼,finally 塊中的程式碼也總是會被執行。這通常是用來釋放資源,比如關閉檔案流或資料庫連線。

簡言之,finally 是你整理遊戲場地,確保一切都已妥善處理後才離開的保障。它保證了,在你完成遊戲之後,不管結果如何,都會有一些後處理工作被執行以維持場地的正常運作。

相關文章