是否需要java';什么是最终确定方法?

是否需要java';什么是最终确定方法?,java,finalize,Java,Finalize,我读到的关于java finalize方法的所有内容都说不能使用它。似乎它几乎从未保证会被调用,甚至在调用时也可能出现问题 还有一些其他问题会问什么时候使用它,而且似乎普遍的共识是永远不会 我自己从来没有使用过它(主要是因为警告不要使用),我也没有在任何地方看到过它 是否有合适的情况?是否存在没有其他选择的情况 如果没有,为什么会有?是否有内部类使用它并要求该方法可用?或者只是一些不该出现的东西 我对什么时候应该使用它(答案是“从不”)不太感兴趣,但我想澄清一下为什么它会出现,因为答案是“从不”

我读到的关于java finalize方法的所有内容都说不能使用它。似乎它几乎从未保证会被调用,甚至在调用时也可能出现问题

还有一些其他问题会问什么时候使用它,而且似乎普遍的共识是永远不会

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

是否有合适的情况?是否存在没有其他选择的情况

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


我对什么时候应该使用它(答案是“从不”)不太感兴趣,但我想澄清一下为什么它会出现,因为答案是“从不”。如果它是如此无用和危险,为什么它没有被折旧和删除呢?

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

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

(*)不要使用它,它叫
不安全
,是有原因的

编辑:回答您评论中的问题

java API出于某种原因需要它吗?

是和否。它必须存在的状态。Java库中的一些类也使用它(例如,当它们处理文件时),但是没有Java API要求您为类实现它

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

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

当垃圾回收确定不再有对对象的引用时,由垃圾回收器对该对象调用

但是它确实在所有对象上看到了
finalize
方法,因为
Object
——并且默认情况下它什么也不做

protected void finalize() throws Throwable { }

向后兼容性。有人最初认为这是一个好主意,但当全世界意识到这不是一个好主意时,为时已晚


这些东西几乎从未被移除过。Java充满了如今被认为是坏主意但却没有被删除的概念——我想到的更多例子是或。

它被推荐的原因是什么,还是早期的垃圾收集器运行起来更可靠?看来,它不应该抓住这些问题。如果它没有流行起来,移除它似乎更安全。我知道java喜欢贬低事物,但仍然不删除它们。有什么理由至少没有贬值吗?我不认为它们过去更可靠。在人们试图使用它的过程中,一些危险逐渐为人们所知。更不可靠的可能来自今天的JAva GCing(由于更多的内存和尽可能延迟GC的策略)。我的理解是,
finally()
主要用于释放不受GC控制且释放不重要的资源(即,如果JVM关闭,它们将自动释放)-比如在使用非Java组件、DLL等时,通过一些本机代码分配内存。好吧,这条评论很有帮助。这与@MartinS的回答类似,但对释放资源来说并不重要的区别似乎是一个更好的用途。使用它来摆脱一个资源,我想要回它的内存,但它不会以某种方式离开系统如果JVM关闭,则会出现可怕的状态,这似乎是一种更安全的使用方式。@Matthew我提到的示例也被认为是非关键资源。即使JVM不控制内存,但如果JVM关闭,操作系统仍会释放内存。只是您不希望长时间运行的程序出现内存泄漏:)我明白为什么在这种情况下你会考虑它,但是如果不能保证它会运行,你会想依靠这些资源来释放这些资源吗?我真的没有做过这样的事情,但考虑到不可预测性,这些资源似乎仍有很好的机会不能被正确释放。这就是为什么我说“作为最后手段”。当程序员忘记在某个地方释放资源时,这仍然比什么都不做要好,因为你至少有机会最终调用
finalize
。@Alex我的问题类似,但我不认为完全一样。我问的不是为什么我会使用它(我不应该),而是为什么它首先在那里(考虑到我不应该)。JavaAPI出于某种原因需要它吗?出于某种原因,JVM必须在所有对象上看到该方法吗?或者,是否存在根本没有其他选择的情况?(第三个问题由您链接的问题解决,但前两个问题没有解决)。@Alex我编辑了我的标题,以便更清楚地区分这一点。好的,要求它在那里,但给出的唯一原因是终结器提供了释放自动存储管理器无法自动释放的资源的机会。在这种情况下,简单地回收对象所使用的内存是不可能的