我读过的关于java finalize方法的所有内容都说 NOT 来使用它。它似乎几乎永远不会被保证被调用,即使它存在也可能出现问题。
还有一些问题要问何时使用它,似乎普遍的共识是从不。
我自己从未使用它(主要是因为没有警告),我没有看到它在任何地方使用过。
是否有任何合适的案例?有没有其他选择的情况?
如果没有,为什么会出现?是否有内部类使用它并要求方法可用?或者它只是不应该存在的东西?
我对使用它时没有那么感兴趣(已经用“从不”回答),但澄清为什么它甚至给出了“从不”的回答。如果它是如此无用和危险,为什么它没有被折旧和删除?
答案 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 { }