定稿
Java 对象可以声明 finalize
方法。在 Java 释放对象的内存之前调用此方法。它通常如下所示:
public class MyClass {
//Methods for the class
@Override
protected void finalize() throws Throwable {
// Cleanup code
}
}
但是,Java 终结的行为有一些重要的警告。
- Java 不保证何时调用
finalize()
方法。 - Java 甚至不保证在运行应用程序的生命周期中某个时候会调用
finalize()
方法。 - 唯一可以保证的是,在删除对象之前将调用该方法…如果删除该对象。
上面的警告意味着依靠 finalize
方法执行必须及时执行的清理(或其他)操作是一个坏主意。过度依赖最终确定可能导致存储泄漏,内存泄漏和其他问题。
简而言之,极少数情况下,最终确定是一个很好的解决方案。
终结者只运行一次
通常,对象在完成后将被删除。但是,这并不是一直发生的。考虑以下示例 1 :
public class CaptainJack {
public static CaptainJack notDeadYet = null;
protected void finalize() {
// Resurrection!
notDeadYet = this;
}
}
当 CaptainJack
的实例变得无法访问且垃圾收集器试图回收它时,finalize()
方法将为 notDeadYet
变量分配对实例的引用。这将使实例再次可达,垃圾收集器不会删除它。
问题:杰克船长不朽吗?
答:没有。
问题是 JVM 只会在其生命周期内对对象运行一次终结器。如果将 null
分配给 notDeadYet
,导致再次无法访问已恢复的实例,则垃圾收集器将不会在该对象上调用 finalize()
。