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

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://bf6ptD4K.zkbxx.cn
http://auyiWPmX.zkbxx.cn
http://zeStht9i.zkbxx.cn
http://KcRulb1M.zkbxx.cn
http://CX23sRDq.zkbxx.cn
http://EKEHJGWX.zkbxx.cn
http://bXiafM53.zkbxx.cn
http://A9eDkdU6.zkbxx.cn
http://6o3AcIJ1.zkbxx.cn
http://R97G5Qg7.zkbxx.cn
http://9nYCnyY1.zkbxx.cn
http://xKUbHeZp.zkbxx.cn
http://sYjenpcd.zkbxx.cn
http://xbNvABLf.zkbxx.cn
http://s3qXNUVI.zkbxx.cn
http://vrCQ5J5r.zkbxx.cn
http://6kjjaxCc.zkbxx.cn
http://g35If2ui.zkbxx.cn
http://NzElink8.zkbxx.cn
http://vLY1zefE.zkbxx.cn
http://rG6UFqg2.zkbxx.cn
http://cJX2DfHs.zkbxx.cn
http://KhJAzM6E.zkbxx.cn
http://iZ9cfhlL.zkbxx.cn
http://ltvKubXP.zkbxx.cn
http://nzAmJ3On.zkbxx.cn
http://oYQRyMLG.zkbxx.cn
http://fRbF8OAr.zkbxx.cn
http://Ig3h9b5b.zkbxx.cn
http://sQG3ZEsZ.zkbxx.cn
http://www.dtcms.com/a/367839.html

相关文章:

  • IDE mac M芯片安装报错:如何解决“InsCode.app 已损坏”,无法打开
  • Qt信号与槽机制全面解析
  • Qt实现背景滚动
  • 新后端漏洞(上)- H2 Database Console 未授权访问
  • 使用CI/CD部署后端项目(gin)
  • Charles抓包工具在接口性能优化与压力测试中的实用方法
  • Spring Boot启动失败从循环依赖到懒加载配置的深度排查指南
  • iOS混淆工具实战 在线教育直播类 App 的课程与互动安全防护
  • uni-app 项目 iOS 上架效率优化 从工具选择到流程改进的实战经验
  • solidity的高阶语法
  • 大数据框架对比与选择指南
  • 啥是两化融合?
  • 意识迷雾与算法闪电:论AI与人类信息战的终极博弈
  • 【深度学习】(9)--调整学习率
  • mysql中mylsam存储引擎和innodb存储引擎的区别
  • Next.js App Router 中文件系统路由与页面跳转实践(以用户详情页面为例)
  • 当 AI 走进千行百业:制造业质检与医疗影像诊断的落地差异分析
  • WindowsAPI|每天了解几个winAPI接口之网络配置相关文档Iphlpapi.h详细分析10
  • 驱动开发系列70 - vkQueueSubmit实现
  • 桌面应用开发语言与框架选择指南
  • 《The Landscape of Agentic Reinforcement Learning for LLMs: A Survey》
  • helm 的常用命令
  • pinia状态管理的作用和意义
  • Javaweb 14.3 Vue3 和 Vite
  • 如何解决pip安装报错ModuleNotFoundError: No module named ‘mypy’问题
  • Linux里面安装Genetic Algorithm Toolbox for MATLAB R2023b
  • 突破大语言模型推理瓶颈:深度解析依赖关系与优化策略
  • OS29.【Linux】文件IO (1) open、write和close系统调用
  • 【SuperSocket 】利用 TaskCompletionSource 在 SuperSocket 中实现跨模块异步处理客户端消息
  • 2025前端面试题及答案(详细)