原文地址:https://www.baeldung.com/java-finalize

1. 概述

在本教程中,我们将重点关注 Java 语言的一个核心方面——根 Object 类提供的 finalize 方法。

简单地说,这是在特定对象的垃圾收集之前调用的。

2. 使用终结器

当 JVM 确定该特定实例应被垃圾回收时,将调用终结器。此类终结器可以执行任何操作,包括使对象恢复生命。

然而,终结器的主要目的是在对象从内存中删除之前释放它们使用的资源。终结器可以作为清理操作的主要机制,也可以在其他方法失败时作为安全网。

为了理解终结器是如何工作的,让我们看一下类声明:

public class Finalizable {
    private BufferedReader reader;

    public Finalizable() {
        InputStream input = this.getClass()
          .getClassLoader()
          .getResourceAsStream("file.txt");
        this.reader = new BufferedReader(new InputStreamReader(input));
    }

    public String readFirstLine() throws IOException {
        String firstLine = reader.readLine();
        return firstLine;
    }

    // other class members
}

Finalizable类有一个字段reader,它引用一个可关闭的资源。当从此类创建对象时,它会构造一个新的BufferedReader实例,从类路径中的文件中读取。

readFirstLine方法中使用了此类实例来提取给定文件中的第一行。请注意,给定代码中的读取器并未关闭。

我们可以使用终结器来实现这一点:

@Override
public void finalize() {
    try {
        reader.close();
        System.out.println("Closed BufferedReader in the finalizer");
    } catch (IOException e) {
        // ...
    }
}

很容易看出,终结器就像任何普通实例方法一样被声明。

实际上,垃圾收集器调用终结器的时间取决于 JVM 的实现和系统条件,这些是我们无法控制的。

为了立即进行垃圾收集,我们将利用System.gc方法。在实际系统中,我们永远不应该明确调用该方法,原因如下:

  1. 成本高昂
  2. 它不会立即触发垃圾收集——它只是提示 JVM 启动 GC