finalize()是object类中由jvm在对象即将被回收前自动调用的protected临终回调方法,自java 9起已被@deprecated标记为过时,因性能差、不可靠且不保证执行,应优先使用try-with-resources或cleaner替代。

finalize() 方法是 Object 类中一个被标记为 protected 的空方法,它不是用来手动调用的,而是由 JVM 垃圾回收器在对象即将被回收前自动触发的一次回调机会。
它本质上是 JVM 提供给程序员的一个“对象销毁前通知机制”,类似静态代码块之于类加载——属于特定生命周期的钩子。但要注意:
- 它不保证一定会被执行:GC 可能长期不启动,或对象被重新引用而逃逸回收
- 它不保证执行时机:可能延迟很久,甚至到 JVM 退出前才集中调用(如某些 GC 策略)
- 它不能替代显式资源管理:比如打开的文件、网络连接、数据库连接等,必须靠 try-with-resources 或 close() 显式释放
从 Java 9 开始,finalize() 已被标记为 @Deprecated,官方明确不推荐使用。原因包括:
- 性能开销大:带 finalize 的对象需经历至少两次 GC 才能真正回收(第一次标记 + 放入 F-Queue,第二次才清理)
- 行为不可控:F-Queue 中的执行顺序、线程、是否抛异常均无保障,异常会被静默吞掉
- 替代方案更可靠:Cleaner(Java 9+)、PhantomReference 配合 ReferenceQueue,或 try-finally/try-with-resources
finalize 不是“你写了就得自己记着去调”的方法:
- equals 和 toString 是普通实例方法,需要你主动调用(如 obj.equals(other)、System.out.println(obj))
- finalize 是被动触发的:你只需重写它,JVM 在判定该对象可回收后,会自动调用一次(最多一次)
- 即使重写了,也不代表它真会被调用;即使调用了,也不能假设它一定完成或成功执行
如果你需要资源清理或善后逻辑:
- 优先用 try-with-resources(实现 AutoCloseable)
- 对非堆资源(如直接内存、本地句柄),用 Cleaner 注册清理动作
- 避免在 finalize 中做日志、同步、IO、启动线程等任何不可靠操作
- 如果遗留代码里还看到 finalize,建议逐步迁移到 Cleaner 或显式关闭流程
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/278920.html