Java中finalize()操作的顺序
我试图理解一个关于Java垃圾收集器和Java中finalize()操作的顺序,java,oop,garbage-collection,finalize,Java,Oop,Garbage Collection,Finalize,我试图理解一个关于Java垃圾收集器和finalize()方法的练习 public class Five { static int x = 1; class String5 { String s; String5() { this.s = ""+(++x); } public void finalize() { System.out.print(s);
finalize()
方法的练习
public class Five {
static int x = 1;
class String5 {
String s;
String5() {
this.s = ""+(++x);
}
public void finalize() {
System.out.print(s);
}
}
String5 a = new String5();
void f() {
String5 a = new String5();
}
public void finalize() {
System.out.print("H");
}
public static void main(String[] args) {
Five a5 = new Five();
a5.f();
a5 = new Five();
a5.f();
System.gc();
System.runFinalization();
}
}
这个练习要求我预测输出。正确答案是
532H
。我预测输出应该是2H35
,我不明白为什么我的顺序不正确。根据JLS,Java语言没有定义finalize
方法的执行顺序,因此实际顺序是一个实现细节
:
Java编程语言没有对finalize方法调用进行排序。终结器可以按任何顺序调用,甚至可以同时调用
您遇到的顺序似乎建议使用堆栈实现—符合垃圾收集条件的第四个也是最后一个创建的String5
实例首先完成(打印5
),然后是打印3
和2
的第二个和第一个(第三个不符合垃圾收集条件),最后,第一个Five
实例完成并打印H
但是,不同的JDK实现可能会产生不同的顺序。噢。。。因此,当我的老师要求正确的顺序时,问题中有一个缺陷?@EdoardoMeneghini根据JLS,正确的答案可能是没有正确的顺序。“不同的JDK实现可能产生不同的顺序”或者根本不输出,或者不打印所有字符,或者出乎意料地打印出比预期更多的字符。因为a)根本不能保证终结器运行,b)
gc()
和runFinalization()
只是可能被忽略的建议,但是c)垃圾收集/终结仍然可能在没有这些提示的情况下运行,例如,在程序和D的中间,即使没有对象的后续使用,即使在被局部变量引用时,对象也可能被收集,因此第二个<代码>五/代码>实例也可能被收集。