2011-07-29 30 views
0

終結問題假設我有以下類關於Java的

class A { 
      //some attributes 

     @override 
     protected void finalize() throws Throwable { 
       //do something 

     } 
    } 


    class B extends A { 

      @override 
     protected void finalize() throws Throwable { 
      //DONT call super.finalize() 
      //do something 

     } 
    } 

會在這種情況下會發生什麼?調用類A的finalize方法會在某個時候被垃圾回收器調用嗎?

調用它,而不是在子類的finalize方法中調用A的finalize方法(如果垃圾回收器正在調用它)之間有什麼不同?

在什麼情況下,可以不在子類中調用其父類的finalize方法?這種情況的任何例子?

回答

2

首先,顯式調用finalize()方法就像調用任何其他Java方法一樣。它是從不如果您的特定類正在重寫finalize()方法,那麼可以不調用父級的finalize()方法。當然,如果你實現了finalizer guardian pattern,你不需要在你的子類中顯式調用父終結器。

順便說一句,不要依賴finalize()清理資源的方法可以明確清除(如關閉文件句柄等),因爲終結器是非確定性的。另外,請查看presentation by Bob Lee以使用Phantom引用代替終結器。

1

不,只有B的finalize方法會被調用,如果你沒有明確地使用super.finalize()就像其他方法調用一樣。

但是,您應該注意,不要調用超類的finalize方法。您可能會無意中錯過關閉資源或其他東西。

2

您應該始終致電super.finalize()以防止資源泄漏。見thisthis。垃圾回收器總是最多會調用finalize()一次,並且由於多態性,只有重寫方法被明確調用。

請注意,甚至建議撥打finally內的finalize()以確保其被調用。但我會給你更好的建議:完全不依賴finalize。明確地儘快關閉資源並嘗試新的Java 7功能:try with resource

1

回答您的問題,

  1. 垃圾收集器將調用finalize()方法在某個時間點但不能保證。

  2. 垃圾收集將僅在當前對象上調用finalize()。所以在B上調用finalize()將不會調用A上的finalize(),除非使用super.finalize()明確調用。

  3. 如果您希望在垃圾收集對象之前執行一些清理操作,則會調用finalize()方法。現在,如果A和B具有不同的finalize方法的實現,並且B的finalization不依賴於As,那麼您不應該調用父母的finalize方法。 例如,A的finalize()方法釋放某些資源,而專用的類B也釋放某些資源(獨立於As)。以類似的方式,可能有A的其他子類正在使用A的資源(因此不能重寫A的finalize())。在這種情況下,如果您從B調用super.finalize()。最終確定可能會造成麻煩,因爲A所持有的資源被其他子類使用。