我们应该在什么时候在java中使用finalize()方法?

我们应该在什么时候在java中使用finalize()方法?,java,Java,什么时候我们应该在java中真正使用finalize()方法 如果我们想在finalize()方法中关闭连接,那么最好使用下面的代码,因为等待GC调用finalize()方法,然后释放连接是没有意义的 try{ // Connection creation }finally{ //close connection } 所以问题是finalize()方法在今天是否具有相关性?finalize()不仅释放了socket之类的资源,而且还管理了内存。从理论上讲,您不需要在代码中显式调用finaliz

什么时候我们应该在java中真正使用finalize()方法

如果我们想在finalize()方法中关闭连接,那么最好使用下面的代码,因为等待GC调用finalize()方法,然后释放连接是没有意义的

try{
// Connection creation
}finally{
//close connection
}

所以问题是finalize()方法在今天是否具有相关性?

finalize()
不仅释放了socket之类的资源,而且还管理了内存。从理论上讲,您不需要在代码中显式调用
finalize()
。VM会在适当的时间执行此操作。

确实最好通过显式调用方法来释放资源。终结器不一定会立即调用,甚至根本不会调用。他们还增加了一个性能惩罚

但是,终结器仍然可以用作释放资源的安全网,以防客户端忘记显式地进行处置

Joshua Bloch的《有效Java》第二版中的主题“避免终结器”:

[D] 除作为安全网或终止非关键性事件外,不要使用终结器 本地资源。在很少使用终结器的情况下, 记住调用super.finalize。如果使用终结器作为安全网, 记住从终结器中记录无效的用法


简单的答案是永远不会。Finalize()充满了微妙的问题,大大降低了垃圾收集的速度


较长的答案是,也许,也许,在开发过程中,您想检查重要的连接、文件、套接字或其他东西是否已关闭,如果未关闭,则记录警告,以便开发人员可以调查并正确解决问题。

我能想到的使用
finalize()
的唯一用例是:

假设您的类中有一个静态资源(成员),并希望在卸载类时对该资源执行一些清理、终结或登录操作,那么您需要重写
finalize()
方法并执行所有这些操作。

实际上
finalize()
不应使用,尤其不应用于清理资源。如果获取了一个资源,从性能角度来看,最好显式释放该资源,而不是等待JVM调用
finalize()
。您无法预见JVM何时将调用finalize(),如果您使用完资源,您将不必要地保留它更长的时间。
我曾看到有人在finalize方法中取消变量,这是另一种不好的做法,因为它通过扩展GC循环(使用完全不必要的代码行)来降低程序的速度。GC设计用于处理非常好的死物清理过程

finally
finalize
是完全不同的东西。要回答您的问题,不,我在近15年的Java开发中从未实现过finalize方法。@PaulTomblin是的,您是对的,我想在这里展示的是在finalize()方法中关闭连接的替代方法。最好在finally块中关闭连接,而不是等待GC调用finalize(),然后释放连接。使用finally{}当连接被释放时,我可以控制它。希望我说得有道理我的下一个问题是它在今天的场景中有什么相关性可能重复在什么情况下我应该覆盖finalize()方法?@Jyotirup我以前从未实现过
finalize()
finalize()
函数很像
C++
中的
destructor
。若你们应该覆盖它,那个么一定有和资源释放相关的东西。然而,大多数情况下,JVM将帮助您正确地完成它。一个快速的Google给了我这个,我认为前三个链接可能会有帮助。@夏令>代码> < />代码>绝对不类似于C++中的析构函数。析构函数是确定性的——这就是它们对RAII有用的原因。Finalize有几个问题,最重要的是,除了查找bug之外,它对其他任何事情都没有用处。只是不要使用它们——特别是如果你不了解引擎盖下发生了什么(即JVM何时运行终结器以及这会产生什么后果)是的,我通常在finalize中放置断言(并配置VM,以便它在关机时运行终结器),以确保所有资源都得到了正确的处理。在开发过程中捕捉bug很好,但是在生产中不应该使用任何东西。如果您有一个静态资源,您当然不希望每次收集类的实例时都卸载它。如果您需要在关机或其他时间释放静态资源(以及所有资源),请明确地执行此操作。这至少会起作用,与使用finalize相反。如果您的类实际上是一个
单例
对象,一个只加载和卸载一次(在关闭时)的对象,该怎么办在应用程序的生命周期中,你的应用程序恰好只是一个POJO,没有任何框架提供用于关闭/销毁的钩子?我同意@Voo,即使类是单例,你最好显式地打开()和关闭()资源,而不依赖于finalize()来调用。