Java中finalize()操作的顺序

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);

我试图理解一个关于Java垃圾收集器和
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的中间,即使没有对象的后续使用,即使在被局部变量引用时,对象也可能被收集,因此第二个<代码>五/代码>实例也可能被收集。