定稿

Java 物件可以宣告 finalize 方法。在 Java 釋放物件的記憶體之前呼叫此方法。它通常如下所示:

public class MyClass {
  
    //Methods for the class

    @Override
    protected void finalize() throws Throwable {
        // Cleanup code
    }
}

但是,Java 終結的行為有一些重要的警告。

  • Java 不保證何時呼叫 finalize() 方法。
  • Java 甚至不保證在執行應用程式的生命週期中某個時候會呼叫 finalize() 方法。
  • 唯一可以保證的是,在刪除物件之前將呼叫該方法…如果刪除該物件。

上面的警告意味著依靠 finalize 方法執行必須及時執行的清理(或其他)操作是一個壞主意。過度依賴最終確定可能導致儲存洩漏,記憶體洩漏和其他問題。

簡而言之,極少數情況下,最終確定是一個很好的解決方案。

終結者只執行一次

通常,物件在完成後將被刪除。但是,這並不是一直髮生的。考慮以下示例 1

public class CaptainJack {
    public static CaptainJack notDeadYet = null;

    protected void finalize() {
        // Resurrection!
        notDeadYet = this;
    }
}

CaptainJack 的例項變得無法訪問且垃圾收集器試圖回收它時,finalize() 方法將為 notDeadYet 變數分配對例項的引用。這將使例項再次可達,垃圾收集器不會刪除它。

問題:傑克船長不朽嗎?

答:沒有。

問題是 JVM 只會在其生命週期內對物件執行一次終結器。如果將 null 分配給 notDeadYet,導致再次無法訪問已恢復的例項,則垃圾收集器將不會在該物件上呼叫 finalize()

1 - 請參閱 https://en.wikipedia.org/wiki/Jack_Harkness