是否需要java的finalize方法?

时间:2016-02-27 06:53:34

标签: java finalize

我读过的关于java finalize方法的所有内容都说 NOT 来使用它。它似乎几乎永远不会被保证被调用,即使它存在也可能出现问题。

还有一些问题要问何时使用它,似乎普遍的共识是从不

我自己从未使用它(主要是因为没有警告),我没有看到它在任何地方使用过。

是否有任何合适的案例?有没有其他选择的情况?

如果没有,为什么会出现?是否有内部类使用它并要求方法可用?或者它只是不应该存在的东西?

我对使用它时没有那么感兴趣(已经用“从不”回答),但澄清为什么它甚至给出了“从不”的回答。如果它是如此无用和危险,为什么它没有被折旧和删除?

2 个答案:

答案 0 :(得分:3)

向后兼容性。有人首先认为这是一个好主意,然后当世界意识到这不是一个好主意时,为时已晚。

这些东西几乎没有被删除。 Java充满了现在被认为是坏主意但仍未被删除的概念 - 我想到的更多例子是clone()Thread.stop()

答案 1 :(得分:2)

您可以使用它并且可以接受的一个用例是释放不受JVM控制的资源,即不会被释放的资源。例如,必须手动释放已使用sun.misc.Unsafe(*)分配的内存,因为它不会被垃圾回收。因此,如果以前没有释放内存,你可以使用finalize方法作为最后的手段释放内存 - 只是为了确保你的程序没有内存泄漏。但是这些情况相当罕见,而今天Java提供了更好的替代方案,例如Java 7中引入的AutoClosable接口。

您可以在OpenJDK源代码中找到更多示例,例如FileInputStream使用finalize方法确保它已关闭。

(*)不要使用它,因为某种原因,它被称为Unsafe

修改:评论中的问题解答

由于某些原因,java API是否需要它?

是和否。 Java Language Specification表明它必须存在。此外,Java库中的某些类使用它(例如,当它们处理文件时),但是没有Java API要求您为类实现它。

由于某种原因,JVM是否必须在所有对象上看到该方法?

好的是,因为JLS这样说,垃圾收集器会为它收集的每个对象调用它。

  

当垃圾收集确定没有对该对象的更多引用时,由对象上的垃圾收集器调用。

但它确实会在finalize implements it之后的所有对象上看到Object方法 - 并且默认情况下它不执行任何操作。

protected void finalize() throws Throwable { }