finalize()自Java 9起被弃用、Java 18彻底移除,因其调用时机不确定、性能开销大、线程不安全、异常被吞且无法保证执行;应改用AutoCloseable+try-with-resources、Cleaner或显式释放。

Java 中 finalize() 方法已被标记为 @Deprecated,自 Java 9 起不推荐使用,Java 18 开始彻底移除(JEP 421),因此不建议重写 finalize,也不应依赖它来释放资源。
为什么 finalize 不该被重写
该方法由垃圾回收器在对象真正回收前调用,但存在严重问题:
- 调用时机不确定:GC 可能永远不运行,或延迟极久,导致资源长期泄漏
- 性能开销大:启用 finalize 的对象需经历至少两次 GC 才能回收(称为“finalization queue”机制)
- 线程不安全:finalize 在专用 Finalizer 线程中执行,可能与主线程竞争资源
- 异常会被吞掉:finalize 中抛出的未捕获异常不会传播,仅被忽略,难以调试
- 无法保证执行:JVM 退出时,未执行的 finalize 可能直接跳过
替代 finalize 的正确做法
资源清理应主动、及时、可预测。推荐以下方式:
- 实现 AutoCloseable 接口 + try-with-resources:适用于文件、网络连接、数据库连接等需要显式关闭的资源
- 使用 Cleaner(Java 9+):轻量、无性能惩罚的清理机制,基于虚引用(PhantomReference),比 finalize 更可靠
-
显式释放 + 文档约定:在类文档中明确说明需调用
close()或shutdown(),并提供默认空实现防止误用
示例(Cleaner):
CWMS 2.0功能介绍:一、 员工考勤系统,国内首创CWMS2.0的企业员工在线考勤系统。二、 自定义URL Rewrite重写,友好的搜索引擎 URL优化。三、 代码与模板分离技术,支持超过5种类型的模板类型。包括:文章、图文、产品、单页、留言板。四、 购物车功能,CWMS2.0集成国内主流支付接口。如:淘宝、易趣、快钱等。完全可媲美专业网上商城系统。五、 多语言自动切换 中英文的说明。六、
立即学习“Java免费学习笔记(深入)”;
public class Resource {
private static final Cleaner cleaner = Cleaner.create();
private final Cleanable cleanable;
private final ByteBuffer buffer;
public Resource() {
this.buffer = ByteBuffer.allocateDirect(1024);
this.cleanable = cleaner.register(this, new ResourceCleaner(buffer));
}
// 清理动作封装为 Runnable
private static class ResourceCleaner implements Runnable {
private final ByteBuffer buffer;
ResourceCleaner(ByteBuffer buffer) { this.buffer = buffer; }
public void run() { CleanerTest.freeDirectBuffer(buffer); }
}
// 显式清理(可选,用于提前释放)
public void close() { cleanable.clean(); }
}
如果旧代码里还有 finalize ……
请尽快迁移。若暂时无法删除,注意:
- 必须调用
super.finalize()(否则父类清理逻辑丢失) - 不要在 finalize 中重新使对象“复活”(如将 this 赋值给静态变量),这会导致内存泄漏且破坏 GC 正确性
- 避免任何耗时操作或同步块,否则会阻塞 Finalizer 线程,拖慢整个 JVM 的回收
基本上就这些。finalize 是个历史包袱,现代 Java 开发中应当完全绕过它。










