最近,OpenJDK 邮件组 core-libs-dev 里出现了一封邮件,建议弃用Object 类的finalize() 方法。
弃用Object 类的方法将会是一件非常不寻常的事情。Java 从 1.0 开始就有了finalize() 方法,不过这个方法一直被认为是一个糟糕的设计,也是Java 平台的一个遗留的大“毒瘤”。
垃圾回收器会特别对待覆盖了finalize() 方法的对象。一般情况下,在垃圾回收期间,一个无法触及的对象会立即被销毁。不过,覆盖了finalize() 方法的对象会被移动到一个队列里,一个独立的线程遍历这个队列,调用每一个对象的finalize() 方法。在finalize() 方法调用结束之后,这些对象才成为真正的垃圾,等待下一轮垃圾回收。
Java 的这种机制与 C++ 里的 RAll 模式类似,创建对象的时候分配资源(比如文件句柄),在销毁对象时自动释放资源。
不过,析构并不能安全地实现资源的自动管理,因为垃圾回收器并没有运行时间上的保证。也就是说,并不存在任何一种机制可以把资源的释放与对象的生命周期完全绑定在一起,如果处理不好还会耗尽资源。
析构的使用已经偏离了它的设计初衷。
多年来,Oracle(以及之前的 Sun)建议开发者避免在一般的应用里使用析构。弃用析构意味着向彻底移除迈出了第一步,不过现在能做的也就是在使用析构时给出编译警告。
现在并没有任何有关彻底移除析构机制的时间表,部分原因是因为 Java 平台上仍然存在一些使用析构的场景,这些场景与资源使用的管理并没有联系。已经有人在考虑如何对这些场景进行迁移,以便移除对析构机制的依赖。
如果 Java 9 不会弃用析构(看起来不太可能),那么最早有可能会在 Java 10 里弃用。不过,最终是不是会在 Java 10 里弃用,或者在更晚的版本里,目前尚无定论。
评论