当前位置: 首页 > ds >正文

finalize() 方法介绍

1、什么是 finalize() 方法?

        finalize() 方法是 Java 中 java.lang.Object 类提供的一个方法,是JVM回收该垃圾象内存之前调用的方法,其声明如下:

protected void finalize() throws Throwable
  • 它是 ​Object 类的一个 ​protected受保护的方法,​所有 Java 类都默认继承了这个方法。
  • finalize() 方法是在垃圾回收器(Garbage Collector, GC)准备回收某个对象所占用的内存之前,由 JVM 自动调用的。​(垃圾回收之前自动调用
  • 可以重写该方法,用于在对象被销毁前执行一些清理工作​(如关闭资源、释放外部链接等)。
  • 方法可以抛出 ​Throwable​(包括 Exception 和 Error),但一般不建议抛出异常
  • 默认的 Object.finalize() 是一个空实现,什么都不做

2、finalize() 的基本工作原理

        当一个对象没有任何引用指向它​(成为垃圾),垃圾回收器会在某个不确定的时间将其标记为可回收。

        在真正回收该对象的内存之前,​JVM 会调用该对象的 finalize() 方法(如果该对象重写了此方法)​

        执行顺序:

                1、对象成为垃圾

                2、垃圾回收器发现该对象可被回收

                3、在回收该对象内存之前,JVM 会调用该对象的 finalize() 方法(如果存在)​。

                4、垃圾回收器在某个时间点真正回收该对象占用的内存。

⚠️ 注意:​调用 finalize() 并不意味着对象一定会被回收!​​ 甚至也有可能通过 finalize() 方法处理来“复活”对象(极为罕见且不推荐)。

3、重写 finalize() 方法(代码示例)

public class User{private String name;public User(String name) {this.name = name;System.out.println(name + " 对象已创建");}@Overrideprotected void finalize() throws Throwable {try {System.out.println(name + " 对象即将被垃圾回收,finalize() 被调用!");// 可以在这里执行一些资源释放逻辑,但不保证一定会执行} finally {super.finalize(); // 调用父类的 finalize(一般无实际意义)}}
}

测试代码

public class Test {public static void main(String[] args) {new User("TestObject");// 提醒 JVM 进行垃圾回收(但不保证马上执行!)System.gc();// 提醒 JVM 进行 finalize 线程的处理System.runFinalization();System.out.println("程序结束");}
}

输出结果:

TestObject 对象已创建
TestObject 对象即将被垃圾回收,finalize() 被调用!
程序结束

注意:输出结果可能不保证顺序,也不保证 finalize 一定会被调用!

4、finalize() 的特点

  1. ​调用时机不确定​

    • finalize() 的调用是由 ​垃圾回收器控制的,​无法控制它何时执行,甚至不保证一定会执行
    • 即使调用了 System.gc() 或 System.runFinalization(),也只是建议​ JVM 执行 GC,不保证效果。
  2. ​不保证一定会被执行​

    • 如果 JVM 在对象成为垃圾后直接回收内存,而没有调用 finalize(),那么该方法就不会被执行。
    • 在程序退出时,某些未被回收的对象的 finalize() 也可能根本不会被调用。
  3. ​性能开销大​

    • 使用 finalize() 会 ​增加垃圾回收的负担,JVM 需要额外维护一个 Finalizer 队列与线程来处理它。
    • 导致 ​GC 变慢,对象回收延迟
  4. ​不要依赖它释放关键资源​

    • 关闭文件、数据库连接、网络连接等,​绝对不要依赖 finalize() 来释放资源,因为它可能永远不会被调用!

5、做资源清理时推荐的方式

         1. ​使用 try-with-resources(Java 7+ 以后)​

                代码示例:

try (FileInputStream fis = new FileInputStream("test.txt")) {// 资源处理
} catch (IOException e) {e.printStackTrace();
}
// fis 会自动调用 close(),无需 finalize!

        ​2.手动在 finally 块中调用 close()​

FileInputStream fis = null;
try {fis = new FileInputStream("test.txt");// 资源处理
} catch (IOException e) {e.printStackTrace();
} finally {if (fis != null) {try {fis.close(); // 关闭} catch (IOException e) {e.printStackTrace();}}
}

        做资源清理时​避免使用 finalize(),在 ​Java 9 开始,finalize() 方法已被标记为 @Deprecated(since="9"),表示不推荐使用,未来可能会被移除。Java 官方文档明确指出:​不应依赖 finalize() 进行必要的清理工作

6、补充:finalize() 的极端情况:对象“复活”

@Override
protected void finalize() throws Throwable {System.out.println("finalize() 被调用,尝试复活对象");SomeClass.saved = this; // 不要这样做!
}

        在极少数情况下,在 finalize() 方法中将 this 赋值给某个静态变量,可能让对象“复活”​​(即暂时不被回收),但这种做法极其不推荐,会导致内存泄漏和不可预测的行为

http://www.xdnf.cn/news/20266.html

相关文章:

  • unity 接入火山引擎API,包括即梦AI
  • flutter-使用fluttertoast制作丰富的高颜值toast
  • 从 ETL 到 Agentic AI:工业数据管理变革与 TDengine IDMP 的治理之道
  • Android8 binder源码学习分析笔记(二)
  • Java 操作 Excel 全方位指南:从入门到避坑,基于 Apache POI
  • Spring Boot 源码深度解析:揭秘自动化配置的魔法
  • AR技术:电力巡检的智能升级之路
  • Python的RSS/Atom源解析库feedparser
  • 【微知】vscode如何开启markdown的review模式?
  • 飞算JavaAI炫技赛:在线图书借阅平台的设计与实现
  • 【完整源码+数据集+部署教程】雪崩检测与分类图像分割系统源码和数据集:改进yolo11-HSFPN
  • 网页版的云手机都有哪些优势?
  • C++(Qt)软件调试---bug排查记录(36)
  • 如何根据Excel数据表生成多个合同、工作证、录取通知书等word文件?
  • 【自动化实战】Python操作Excel/WORD/PDF:openpyxl与docx库详解
  • WinForms 项目里生成时选择“首选目标平台 32 位导致有些电脑在获取office word对象时获取不到
  • EXCEL列数据前面补零
  • GD32入门到实战35--485实现OTA
  • 警惕!你和ChatGPT的对话,可能正在制造分布式妄想
  • 计算机网络2 第二章 物理层——用什么方式传输邮件
  • 狗都能看懂的HunYuan3D 1.0详解
  • 一种基于注解与AOP的Spring Boot接口限流防刷方案
  • C#海康车牌识别实战指南带源码
  • VAE(变分自动编码器)技术解析
  • iOS混淆工具实战 在线教育直播类 App 的课程与互动安全防护
  • FairGuard游戏加固产品常见问题解答
  • 云市场周报 (2025.09.05):解读腾讯云AI安全、阿里数据湖与KubeVela
  • C语言中常见的数据结构及其代码实现
  • 数据传输优化-异步不阻塞处理增强首屏体验
  • 自演化大语言模型的技术背景