finalize() 方法

这是 Object 类的受保护非静态方法。此方法用于在对象从内存中删除之前对对象执行某些最终操作或清理操作。

根据文档,当垃圾收集确定没有对该对象的更多引用时,该方法由对象上的垃圾收集器调用。

但是,如果对象仍然可以访问,或者当对象符合条件时没有运行垃圾收集器,则无法保证调用 finalize() 方法。这就是为什么最好不要依赖这种方法。

在 Java 核心库中可以找到一些用法示例,例如在 FileInputStream.java 中:

protected void finalize() throws IOException {
    if ((fd != null) &&  (fd != FileDescriptor.in)) {
        /* if fd is shared, the references in FileDescriptor
         * will ensure that finalizer is only called when
         * safe to do so. All references using the fd have
         * become unreachable. We can call close()
         */
        close();
    }
}

在这种情况下,如果该资源之前尚未关闭,则它是关闭资源的最后机会。

一般来说,在任何类型的应用中使用 finalize() 方法都是不好的做法,应该避免使用。

终结器不是用于释放资源(例如,关闭文件)。当(如果!)系统在堆空间上运行不足时,将调用垃圾收集器。当系统在文件句柄上运行不足或由于任何其他原因,你不能依赖它来调用它。

终结器的预期用例是针对即将被回收的对象,以通知其他对象即将发生的厄运。现在为此目的存在一种更好的机制 - java.lang.ref.WeakReference<T> 类。如果你认为需要编写 finalize() 方法,那么你应该考虑是否可以使用 WeakReference 来解决相同的问题。如果这不能解决你的问题,那么你可能需要在更深层次上重新考虑你的设计。

进一步阅读这里大约是从由 Joshua 布洛赫“有效的 Java”的书 finalize() 方法的项目。