2016-02-27 25 views
6

我已閱讀的關於java finalize方法的所有內容均表示使用而不是。看起來它幾乎不能保證被調用,即使它出現問題也可能出現問題。是否有任何需要java的finalize方法?

還有一些問題提出了什麼時候使用它,似乎普遍的共識是從不

我從來沒有用它自己(因爲警告不主要),我還沒有看到它的任何地方使用。

是否有任何適合的情況?有沒有別的辦法的情況?

如果不是,那爲什麼呢?是否有內部類使用它並要求方法可用?或者它只是不應該在那裏的東西?

我不在的時候,我應該使用它那麼多的興趣(已回答「從不」),但澄清爲什麼它甚至沒有給出「絕不」這個問題的答案。如果它如此無用和危險,爲什麼它沒有被折舊和清除?

+0

http://stackoverflow.com/questions/158174/why-would-you-ever-implement-finalize – Alex

+0

@Alex我的問題是類似的,但我不認爲它是完全一樣的。我並沒有問這麼多爲什麼我會用它(我不應該)爲什麼它首先出現在那裏(因爲我不應該)。由於某種原因,java API是否需要它?由於某種原因,JVM是否必須在所有對象上看到該方法?或者有沒有其他的選擇? (其中的第三個問題由你鏈接的問題解決,但前兩個不是)。 – Matthew

+0

@Alex我編輯了我的標題,使這個區別更清晰一些。 – Matthew

回答

3

向後兼容性。有人首先想到這將是一個好主意,然後當世界意識到這不是一個好主意時,已經太晚了。

這些東西幾乎沒有刪除。 Java充滿了現在被認爲是壞主意的概念,但還沒有被移除 - 我想到的更多例子是clone()Thread.stop()

+0

是否有一點被推薦,或者是早期的垃圾收集器在運行時更可靠?看來它不應該出現問題。如果它沒有得到解決,似乎應該更安全地將其刪除。我知道java喜歡貶低東西,但仍然沒有刪除它們。有沒有任何理由說它至少沒有被折舊? – Matthew

+1

我不認爲他們過去更可靠。隨着人們試圖使用它,一些危險在時間上被人們所瞭解。今天的JAva GCing可能會有更多的不可靠性(由於更多的內存和儘可能延遲GC的策略)。 –

+1

我的理解是'finally()'主要是允許釋放不受GC控制的資源*和*釋放並不重要的資源(即,如果JVM關閉,它們將自動釋放) - 例如分配內存通過一些本地代碼處理非Java組件,DLL等。 –

2

一個用例,你可能會使用它,它是可以接受的是不屬於JVM即是不會被釋放,否則的控制下的資源。例如,使用sun.misc.Unsafe(*)分配的內存必須手動釋放,因爲它不會被垃圾收集。所以你可以使用finalize方法作爲釋放內存的最後手段,如果它之前沒有被釋放 - 只是爲了確保你的程序沒有內存泄漏。但這些案件是相當罕見的,今天Java提供像AutoClosable接口,它已經在Java 7中推出更好的替代品

您可以在OpenJDK的源代碼中的例子,例如FileInputStream使用的finalize方法來確保它關閉了。

(*)不要使用它,這就是所謂的Unsafe是有原因的。

編輯:解答從您的評論

不要在Java API需要它由於某種原因,問題嗎?

是和否。 Java Language Specification指出它必須存在。還有一些Java庫中的類使用它(例如,當它們處理文件時),但沒有Java API要求您爲類實現它。

是否JVM必須看到由於某種原因,所有對象的方法?

嗯,是再次因爲JLS是這麼說的和垃圾收集器調用它的每個對象它收集。

當垃圾回收確定沒有更多對該對象的引用時,由對象上的垃圾回收器調用。

但它確實看到的所有對象的finalize方法,因爲Objectimplements it - 它的確每默認沒什麼。

protected void finalize() throws Throwable { } 
+0

我可以明白爲什麼你會考慮這種情況,但考慮到它不能保證它會運行,它會是你想依賴來釋放這些資源的東西嗎?我沒有真正做過這樣的事情,但似乎仍然有很好的機會,因爲這些資源是不可預測的,所以這些資源不會被正確地釋放。 – Matthew

+1

這就是爲什麼我說「作爲最後的手段」。當程序員忘記釋放某個資源時,它總比沒有做任何事情更好,因爲你至少很有可能會最終調用finalize。 – MartinS

相關問題