最终不推荐使用java.lang.Object.finalize()

吉菲

钕因此,敲定(),已经受够了他自己的不可靠性,走出对象的会议室中,永远不会再看到的,或者说我们愿意相信。

尽管许多人可能还没有意识到,但随着JDK 9版本的到来,finalize() 弃用了。 不相信我,请查看Java 9文档 ! 读者请注意, 弃用并不一定意味着要删除或将来要删除 。 这是一种指示,用于指示应避免(如果可能)带注释的元素,并且有可能在Java平台的将来版本中将其删除。

目前,还不确定是否将finalize()标记为要删除。 我个人不相信它将被删除,但是我不确定。 我所能做的就是,JDK 11的Early Access Builds尚未将其删除,并且由于它是Java生态系统中每个类都继承的方法,因此我直觉地劝说我相信它会继续存在。

但是,如果元数据至少表明了API编写者的意图,那么至少在编写时,似乎就不会删除它-至少在不久的将来不会。 我们可以通过运行并分析以下代码的结果来诱发这种情况:

/* Note that this uses language features only available in Java 10 and 11, namely, local variable type inference. The use of this feature within Lambda Expression arguments came about in Java 11 and is used in this article. Java 10 is set to be released 6 days following the publishing of this article. You may learn more about local variable type reference @ bit.ly/VarJava */
import java.lang.annotation.Annotation;
...
var annos = Object.class.getDeclaredMethod("finalize", (Class<?>[]) null ) .getAnnotations();
for (var anno : annos) System.out.println(anno + "\n");
Output: @java.lang.Deprecated( forRemoval =false, since="9")

我们运行该代码的原因很明显,这是通过编程显示java.lang.Object.finalize()未被标记为要删除。

对finalize()的弃用在某种程度上可以看作是长期以来众所周知的锦上添花的仪式。

Joshua Bloch一直追溯到2001年,在他的经典电影《 Effective Java》 (对于认真的Java开发人员应该是必读的)的第一版中,他警告了依赖finalize()危险

Sun(及其后的Oracle) 长期以来一直警告Java开发人员使用Finalization,以及为什么几乎(如果不是彻底的话)总是一个不好的主意。 开发finalize()的主要动机是能够处理代码中的“无法访问的对象”,例如本机资源。

过去,人们可能会试图按如下方式使用finalize()。

关于我的环境的一些注意事项:我将在Linux Mint MATE上使用JDK 11的早期访问版本。

可以finalize()可靠地关闭您的流吗?

让我们写一个以MVC建筑模式为模型的电话簿。
首先Model ,一个称为Contact的POJO bean。
其次,控制器,称为电话簿的类。
第三,视图,我们的主要类,称为Finalize。
运行时,这是输出。
分析。

花一点时间看一下代码。 这里要掌握的主要事情是,我们依靠finalize()进行一些清理:关闭java.io.PrintWriter流。 现在,将注意力吸引到Finalize类的第16和17行。 请注意,我们都将TelephoneBook的实例设置为null,并向Garbage Collector坦率地建议现在可能是运行的好时机。 回想一下,System.gc()不是垃圾收集器的直接触发器,而finalize()不是析构函数。 都不需要运行 。 这一切的核心是,垃圾收集器会在需要时运行,而我们(出于实际目的)无法控制它。

您是否注意到垃圾收集器已运行并且在我们的示例中调用了finalize()? 试试这个实验。 删除Finalize类的第16行或第17行,然后查看是否调用了finalize()方法。 我不确定是不是,尽管我不确定。 对我来说,它一再没有。 请记住,我们(至少在大多数实际情况下)无法确定性地控制垃圾收集器的运行时间。

因此,如果我们依靠finalize()关闭OutputStream,那么我们将进行草率的编程。

您知道为什么finalize()是个坏主意吗? 这只是许多示例中的一个,但是消息很明确: 因为我们不能保证将调用finalize()或确定何时运行GC,所以我们不能可靠地使用finalize()完成关闭任务,例如作为关闭的I / O流 。 如果我们不得不关闭SSLSocket怎么办? 还是JDBC连接? 还是JNI资源? 我将它留给读者的想象力(或噩梦)来思考可能造成的混乱。

总结思想

Java 9是一个期待已久的仪式,它证明了一种古老的真理:您不能依靠finalize()在清理之后进行清理。 表现并明确地和其他方式清理资源。 还应指出,finalize()还有其他问题,即: 性能,死锁和挂起 [1]。

要更深入地了解为什么System.gc()是不好的做法,请访问此处:

像我们其他人一样鄙视finalize()吗? 还是您认为这还是个好主意? 在下面的评论中让我知道:)

想要来源吗? 在这里抓住它。

您将需要在这里找到JDK 11。

再见,finalize()。 您将不会错过。

对Java感兴趣? 加入我在Facebook上的Java组:

喜欢我的内容? 订阅我的邮件列表:

别忘了给它一个…。 ;)

IEmoji.com

参考文献

[1] — JDK 9 API文档:java.lang.Object.finalize()

From: https://hackernoon.com/java-lang-object-finalize-is-finally-deprecated-f99df40fa71

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值