2016-02-27 24 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

相关问题