为何将对象置为null后,finalize方法未抛出空指针异常?
为什么finalize方法未抛出空指针异常?
这是个很典型的Java垃圾回收认知误区问题,我来给你理清楚背后的逻辑:
核心原因:finalize执行时对象还未被销毁
当你把f1、f2这两个引用变量置为null,只是切断了栈上的引用和堆内存中对象实例之间的关联,但对象本身并没有立刻从堆里消失——它只是变成了垃圾收集器的目标对象。
而finalize()方法的调用时机是:垃圾收集器在确定对象可回收后,真正销毁这个对象之前。也就是说,在finalize()执行的这一刻,对象依然完整地存在于堆内存中,方法里的this关键字依然指向这个有效的对象实例,自然不会抛出空指针异常。
结合你的代码具体分析
看你的代码执行流程:
- 创建了两个Person对象,
f1的a被赋值为10,f2的a保持默认值0; - 把
f1、f2置为null,此时两个对象没有任何强引用指向它们; - 调用
System.gc()(JVM收到这个建议后触发了垃圾回收); - 垃圾收集器找到这两个无引用对象,分别调用它们的
finalize()方法:- 对应
f2的对象,a是默认值0,所以输出finalize called0; - 对应
f1的对象,a的值还保留着10,所以输出finalize called10。
- 对应
这也侧面证明了,在finalize执行时,对象的属性数据都还完好,对象本身并未被销毁。
额外提醒:finalize已过时
需要注意的是,finalize()方法在Java 9及以后已经被标记为**过时(@Deprecated)**了,因为它的执行时机完全不可控,甚至可能导致对象复活、内存泄漏等问题。如果需要做资源清理,现在更推荐使用java.lang.ref.Cleaner或者PhantomReference这类更可靠的机制。
内容的提问来源于stack exchange,提问作者Radiance
相关产品推荐
相关产品推荐

