猿问

“对于任何给定对象,JVM 永远不会多次调用 finalize 方法”的含义。在物体复活的情况下?

根据 Java 文档:

对于任何给定对象,Java 虚拟机永远不会多次调用 finalize 方法。

  1. 上述政策可以帮助使对象不朽吗?如果我从 finalize() 方法中一次复活一个对象,那么该对象是否会成为不朽的,因为 JVM 不能第二次在该对象上调用 finalize() 方法?

或者

  1. 如果该对象再次符合 GC 条件(假设指向复活对象的另一个引用符合 GC 条件),那么下次 JVM 将删除该对象而不调用该对象的 finalize() 方法?

我试图通过一些示例代码来验证它并假设第二个是正确的,但需要确认我的理解。


慕桂英4014372
浏览 289回答 1
1回答

慕斯王

根据 ernest_k,它是第 2 个。该对象将被垃圾收集,而无需调用其 finalize() 方法。添加我的示例代码来完成这个答案,我创建它来验证。import java.util.HashSet;import java.util.Set;class Immortal {&nbsp; &nbsp; // making it public and non-fianl to modify from outside&nbsp; &nbsp; public static Set<Immortal> immortals = new HashSet<>();&nbsp; &nbsp; @Override&nbsp; &nbsp; protected void finalize() throws Throwable {&nbsp; &nbsp; &nbsp; &nbsp; System.out.println("Running finalize for " + this);&nbsp; &nbsp; &nbsp; &nbsp; immortals.add(this); // Resurrect the object by creating a new reference&nbsp; &nbsp; }}public class ObjectResurrection {&nbsp; &nbsp; public static void callGC() {&nbsp; &nbsp; &nbsp; &nbsp; // call garbage collection&nbsp; &nbsp; &nbsp; &nbsp; System.gc();&nbsp; &nbsp; &nbsp; &nbsp; // wait for some time to give chance to run garbage collection thread&nbsp; &nbsp; &nbsp; &nbsp; try {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Thread.sleep(10 * 1000);&nbsp; &nbsp; &nbsp; &nbsp; } catch (InterruptedException e) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // TODO Auto-generated catch block&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; e.printStackTrace();&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; public static void main(String[] args) {&nbsp; &nbsp; &nbsp; &nbsp; Immortal immortal1 = new Immortal();&nbsp; &nbsp; &nbsp; &nbsp; Immortal immortal2 = new Immortal();&nbsp; &nbsp; &nbsp; &nbsp; // print objects when they are alive.&nbsp; &nbsp; &nbsp; &nbsp; System.out.println("immortal1 = " + immortal1);&nbsp; &nbsp; &nbsp; &nbsp; System.out.println("immortal2 = " + immortal2);&nbsp; &nbsp; &nbsp; &nbsp; // print immortal set&nbsp; &nbsp; &nbsp; &nbsp; System.out.println("immortal set = " + Immortal.immortals);&nbsp; &nbsp; &nbsp; &nbsp; // make all objects garbage collectable&nbsp; &nbsp; &nbsp; &nbsp; immortal1 = null;&nbsp; &nbsp; &nbsp; &nbsp; immortal2 = null;&nbsp; &nbsp; &nbsp; &nbsp; callGC();&nbsp; &nbsp; &nbsp; &nbsp; // now objects will be null&nbsp; &nbsp; &nbsp; &nbsp; System.out.println("immortal1 = " + immortal1);&nbsp; &nbsp; &nbsp; &nbsp; System.out.println("immortal2 = " + immortal2);&nbsp; &nbsp; &nbsp; &nbsp; // but stays in immortal set&nbsp; &nbsp; &nbsp; &nbsp; System.out.println("immortal set = " + Immortal.immortals);&nbsp; &nbsp; &nbsp; &nbsp; // remove all objects from immortal set, and make them again eligible for GC&nbsp; &nbsp; &nbsp; &nbsp; Immortal.immortals.clear();&nbsp; &nbsp; &nbsp; &nbsp; callGC();&nbsp; &nbsp; &nbsp; &nbsp; // again print the immortal set&nbsp; &nbsp; &nbsp; &nbsp; // this time set will be empty, and those 2 objects will be destroyed by Garbage&nbsp; &nbsp; &nbsp; &nbsp; // Collection,&nbsp; &nbsp; &nbsp; &nbsp; // but this time they will not call finalize, because it is already called&nbsp; &nbsp; &nbsp; &nbsp; // you can notice no output from finalize method in the output this time&nbsp; &nbsp; &nbsp; &nbsp; System.out.println("immortal set = " + Immortal.immortals);&nbsp; &nbsp; }}上述程序的输出(在我的机器上):immortal1 = effective.java.item7.finalizer6.Immortal@70dea4eimmortal2 = effective.java.item7.finalizer6.Immortal@5c647e05immortal set = []Running finalize for effective.java.item7.finalizer6.Immortal@5c647e05Running finalize for effective.java.item7.finalizer6.Immortal@70dea4eimmortal1 = nullimmortal2 = nullimmortal set = [effective.java.item7.finalizer6.Immortal@5c647e05, effective.java.item7.finalizer6.Immortal@70dea4e]immortal set = []
随时随地看视频慕课网APP

相关分类

Java
我要回答