java中finalize的用法_为什么Java 9中不推荐使用finalize()方法?

小编典典

尽管问题是关于Object.finalize方法的问题,但主题实际上是关于 最终确定 机制的整体。该机制不仅包括表面API

Object.finalize,还包括有关对象生命周期的编程语言规范,以及对JVM中垃圾回收器实现的实际影响。

从应用程序的角度,已经写了很多关于为什么难以使用终结处理的文章。看到问题,为什么要实施finalize()?并且Java 9Cleaner是否应优先于定稿?和他们的答案。另请参阅 有效的Java,第3版, 由Joshua

Bloch,项目8。

简要地说,有关使用终结器的问题的几点是:

众所周知,它们很难正确编程

特别是当对象意外无法到达(但正确)时,它们可能会意外运行

最终确定可以轻松打破子类/超类关系

终结器之间没有顺序

给定对象的finalize方法最多由JVM调用一次,即使该对象已“复活”

无法保证最终确定的及时性,甚至根本无法保证

没有明确的注册或注销机制

以上是使用finalization的困难。考虑到上述问题,正在考虑使用终结处理的任何人都应重新考虑。但是这些问题是否足以弃用Java平台中的终结处理?以下各节中说明了几个其他原因。

最终确定可能会使系统易碎

即使您编写的对象正确使用了终结处理,将对象集成到较大的系统中也会导致问题。即使您根本不使用终结处理,将其集成到较大的系统中(其中某些部分使用终结处理)也可能导致问题。通常的问题是,创建垃圾的工作线程需要与垃圾收集器保持平衡。如果垃圾收集器落后了,那么至少某些收集器可以“阻止世界”并进行完整的收集以赶上。终结使这种交互变得复杂。即使垃圾收集器跟上了应用程序线程的速度,结束处理也可能会导致瓶颈并降低系统速度,或者可能导致释放资源时出现延迟,从而导致这些资源的耗尽。这是一个

系统 问题。即使使用终止的实际代码正确无误,在正确编程的系统中仍然可能出现问题。

最终确定会导致安全问题

适用于Java 的 SEI CERT Oracle编码标准

具有一条规则MET12-J:不要使用终结器。(请注意,这是一个有关安全编码的网站。)特别是,它说

终结器使用不当会导致垃圾回收就绪对象的复活,并导致拒绝服务漏洞。

Oracle的Java

SE安全编码指南对

使用终结处理可能引起的潜在安全性问题更为明确。在这种情况下,使用终结处理的代码不是问题。取而代之的是, 攻击者

可以使用终结处理来攻击尚未适当防御的敏感代码。特别是, 准则7-3 / OBJECT-3 规定,

可以通过终结器攻击来访问非最终类的部分初始化实例。攻击者finalize在子类中重写受保护的方法,并尝试创建该子类的新实例。这种尝试失败了……但是攻击者只是忽略了任何异常,而是等待虚拟机对部分初始化的对象执行最终化。发生这种情况时,将finalize调用恶意方法实现,从而使攻击者可以访问this,该引用指向最终确定的对象。尽管仅部分初始化了对象,但攻击者仍可以在其上调用方法…。

因此,平台中终结机制的存在给试图编写高保证代码的程序员带来了负担。

最终确定增加了规格的复杂性

Java平台由多种规范定义,包括语言,虚拟机和类库API的规范。最终确定的影响在所有这些方面都散布得很细,但它反复使它感到存在。例如,完成与对象创建之间的交互非常微妙(已经足够复杂了)。Finalization也已经出现了Java的公共API,这意味着(到目前为止)要求这些API进行演变以保持与先前指定的行为兼容。不断完善这些规范会使最终确定的成本更高。

最终确定给实施增加了复杂性

这主要是关于垃圾收集器的。有几种垃圾回收实现,并且都需要支付实现终结的成本。如果不使用终结处理,这些实现非常擅长将运行时开销降至最低。但是,实现仍然需要存在,并且需要正确且经过良好测试。这是持续的开发和维护负担。

摘要

We’ve seen elsewhere that it’s not recommended for programmers to use

finalization. However, if something is not useful, it doesn’t necessarily

follow that it should be deprecated. The points above illustrate the fact that

even if finalization isn’t used, the mere presence of the mechanism in the

platform imposes ongoing specification, development, and maintenance costs.

Given the lack of usefulness of the mechanism and the costs it imposes, it

makes sense to deprecate it. Eventually, getting rid of finalization will

benefit everyone.

截至撰写本文时(2019-06-04),尚无具体计划从Java中删除终结处理。但是,这样做当然是有意图的。我们已弃用该Object.finalize方法,但尚未将其标记为删除。正式建议程序员停止使用此机制。非正式地知道不应该使用终结处理,但是当然有必要采取正式的步骤。此外,不赞成使用finalize库类中的某些方法(例如ZipFile.finalize)以“删除”,这意味着这些类的最终确定行为可以从将来的版本中删除。最终,我们希望在JVM中禁用终结处理(也许首先是可选的,然后是默认情况下的禁用),

2020-10-09

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值