finalize() Method in Java

14 Apr 2025 | 5 分钟阅读

finalize() 方法java.lang.Object 类的一个 protected 方法。它用于在对象被从内存中移除之前执行清理操作(例如关闭打开的文件、释放内存或关闭连接)。

方法签名

垃圾回收 发现 对象 不再有任何引用时,垃圾回收器会调用对象的 finalize() 方法

finalize() 方法示例

示例

编译并运行

输出

 
Object created
Main method completed
finalize() is called before an object is garbage collected   

解释

该程序演示了如何在 Java 中重写 finalize() 方法,以便在对象被垃圾回收之前执行清理操作。Main 类包含一个构造函数,在创建对象时打印一条消息,并重写 finalize() 方法,在垃圾回收器销毁对象之前打印一条消息。

main() 方法 中,创建一个对象,然后将其显式设置为 null,使其有资格被垃圾回收。调用 System.gc() 来请求垃圾回收,尽管 JVM 可能不会立即执行它。如果垃圾回收器运行(何时运行),将调用重写的 finalize() 方法,打印清理消息。

何时在 Java 中使用 finalize() 方法?

JVM 的垃圾回收器仅收集通过 new 关键字创建的对象。因此,如果我们创建了任何未通过 new 关键字创建的对象,我们可以使用 finalize() 方法执行清理处理(销毁剩余的对象)。

垃圾回收由一个名为垃圾回收器 (GC) 的守护线程执行。该线程在对象被垃圾回收之前调用 finalize() 方法。

Java 提供了各种释放资源的方法,例如用于文件处理的 close() 方法和 destroy() 方法。但是,这些方法需要手动调用,这会带来挑战。

为了应对上述挑战,我们可以在 finally 块中实现 finalize() 方法。它确保即使在用户调用 close() 方法后,finalize() 方法也会运行。我们可以在 finally 块中重写 finalize() 方法来释放对象使用的所有资源。

如何重写 finalize() 方法?

在 Object 类中,finalize() 方法是 protected 的,并且没有实现。因此,我们可以通过重写 Object 类中的 finalize() 方法来在我们的类中使用它,因为 Object 类是所有类的父类。

如果类有清理活动,我们必须显式重写 finalize() 方法。

要记住的重要事项

  • 如果 finalize 方法抛出未捕获的异常,该异常将被忽略,并且该对象的 finalization 将终止。
  • 一旦 finalize 方法在对象上被调用,将不会发生进一步的操作,直到 JVM 确认没有活动线程可以访问该对象,考虑到其他等待 finalization 的对象或类可能采取的任何潜在操作。届时,该对象就可以被回收。
  • Java 虚拟机对于任何给定的对象,其 finalize 方法永远不会被调用超过一次。
  • finalize 方法抛出的任何异常都会中断此对象的 finalization,但会被忽略。
  • 我们也可以重写 finalize() 方法。

注意:自 Java 9 起,由于 finalize() 方法的不可预测性和滥用风险,该方法已被弃用。建议使用 try-with-resources 或显式资源管理等替代方案。

FileInputStream.finalize() 方法与 Object.finalize() 方法之间的区别

Java 中的 finalize() 方法根据其所属类有不同的用途。以下是 FileInputStream 类的 finalize() 方法和 Object 类的 finalize() 方法之间的结构化比较。

方面Object.finalize()FileInputStream.finalize()
目的它允许对象在垃圾回收之前释放资源或执行最终任务。FileInputStream 对象被垃圾回收标记时,它确保主文件描述符被关闭。
Class它定义在属于 java.lang 包的 Object 类中。它定义在属于 java.io 包的 FileInputStream 类中。
实施这是一个通用的清理方法,适用于任何重写它的类,通常用于释放非托管资源。专门管理文件资源(如关闭文件描述符)的清理。
可访问性由于 Object 是 基类,所有对象都可以继承它。仅对 FileInputStream 实例可用。
重写它可以在子类中重写,以自定义特定对象的清理逻辑。FileInputStream 被重写以提供针对文件操作量身定制的资源清理。
调用此方法在垃圾回收过程中自动调用;但是,在当代的 Java 编程实践中,一般不鼓励重写此方法及其用法。如果之前未显式关闭,则在垃圾回收过程中自动调用。
在现代 Java 中使用较少;建议使用 AutoCloseable 和 try-with-resources 等现代替代方案。此方法对于管理文件资源仍然有效;但是,我们建议使用 try-with-resources 来获得更高效的文件处理体验。

Java finalize() 方法选择题

1. Java 中 finalize() 方法的目的是什么?

  1. 初始化对象
  2. 在对象销毁前清理资源
  3. 克隆对象
  4. 为对象分配内存
 

答案 2)

解释: finalize() 方法的目的是在对象从内存中移除之前执行清理操作(例如关闭打开的文件、释放内存或关闭连接)。


2. finalize() 方法何时被调用?

  1. 创建对象时
  2. 克隆对象时
  3. 在对象被垃圾回收之前
  4. 在对象被垃圾回收之后
 

答案 3)

解释: GC 线程在对象被垃圾回收之前调用 finalize() 方法。


3. 关于 finalize() 方法,以下哪个说法是正确的?

  1. 它由垃圾回收器自动调用
  2. 它必须由程序员显式调用
  3. 它用于分配内存
  4. 它不能被重写
 

答案 1)

解释: 垃圾回收由一个名为垃圾回收器 (GC) 的守护线程执行。该线程在对象被垃圾回收之前调用 finalize() 方法。


4. Java 9 中 finalize() 方法为什么被弃用?

  1. 由于垃圾回收的改进,它不再需要
  2. 它不可预测,可能导致性能问题
  3. 它不能被重写
  4. 它不受现代 JVM 的支持
 

答案 2)

解释: 自 Java 9 起,由于 finalize() 方法的不可预测性和滥用风险,该方法已被弃用。


5. 重写 finalize() 方法的正确方法是什么?

  1. public void finalize()
  2. protected void finalize() throws Throwable
  3. private void finalize()
  4. static void finalize()
 

答案 2)

解释: 重写 finalize() 方法的正确方法是使用 protected finalize() 方法。