2014-12-03 128 views
1

我在Java7中實現了一個類。它不會繼承/實現任何東西。它使用Tess4J,所以我認爲最後釋放資源將會很好。所以我推翻這樣的finalize()方法:爲什麼Netbeans警告我敲定?

@Override 
protected void finalize() throws Throwable 
{ 
    try 
    { 
     TessAPI1.TessBaseAPIDelete(handle); 
    } 
    catch(Throwable t) 
    { 
     throw t; 
    } 
    finally 
    { 
     super.finalize(); 
    } 
} 

Netbeans的8.0.2給我警告了這種方法:

finalize declared() 

的NetBeans網站上的描述是不是更有用的對我說:

warns about implementation of Object.finalize() 

我沒有推翻像等號或任何其他方法(也許我應該?)。 你能告訴我爲什麼我會收到這個警告嗎?

+1

相關閱讀:http://weblog.ikvm.net/2003/11/09/FinalizeConsideredHarmful。as Java – 2014-12-03 11:43:31

+0

來自Effective Java的報道:「*終結器是不可預知的,通常是危險的,並且通常是不必要的*」。 – assylias 2014-12-03 11:48:07

+2

捕捉並立即重新拋出異常毫無意義。這種擒縱塊可以被移除,因爲它沒有真正的效果。 – Natix 2014-12-03 11:54:25

回答

4

finalize方法都有它們可以在任意時間任意線程或所謂的甚至從來沒有在所有的問題。和discussed in this question一樣,它們可能會很早就被調用,即當實例方法仍在執行時,所以使用它們來釋放資源是非常危險的。

因此,如果它們對於它們最初的目的不是很有用,那麼在使用它們時總是發出警告是合理的。


如果要實施清理的資源,當客戶端代碼忘了打電話closedispose或任何你提供明確的資源管理(你應該如果有相關的本機資源)代碼可以使用PhantomReference對實例和ReferenceQueue完成。

好處是,您可以控制何時輪詢隊列並執行清理,並且您甚至可以通過讓PhantomReference超出範圍(通常將收集並且未入隊)來選擇退出驗屍清理)在客戶端代碼沒有忘記調用close(它強烈建議執行AutoClosable允許使用try with resources」)的情況。因此,這也解決了性能小的問題,即必須收集具有非平凡finalize方法的對象兩次,因爲執行finalize方法意味着它們再次可達。

0

當jvm轉到gc時調用finalize()。所以也許資源沒有按照你的意願發佈。

最後改用試試。

+0

在對象生命期間多次調用處理,並且它有不同的類型。我是否可以用try-finally包圍每個處理方法代碼(這是否是一個好習慣)? – nuoritoveri 2014-12-03 12:09:02

2

一般來說,大多數Java程序員從來沒有理由實現finalize(),因爲他們自己的代碼只使用已經管理的類(因此它們有自己的終結器)。 (請參閱問題下方的註釋)。

有些開發人員可能不知道垃圾回收器是如何工作的,因此依靠finalize()來完成應該在其他地方完成的清理工作。這個錯誤尤其會導致在測試中不被注意的缺陷,但會導致生產失敗。

出於這個原因,我想警告有關finalize()是合適的。

相關問題