Java终结器guardian似乎不起作用?

Java终结器guardian似乎不起作用?,java,finalize,Java,Finalize,我有一个超类,它使用finalize()方法伸缩构造函数。为了防止子类忘记调用super.finalize,我编写了一个类似的finalizerguardian(EJ条目7) public class Super { public Super() {} { Object finalizerGuardian = new Object() { @Override protected void finalize() {

我有一个超类,它使用finalize()方法伸缩构造函数。为了防止子类忘记调用super.finalize,我编写了一个类似的finalizerguardian(EJ条目7)

public class Super {

    public Super() {}

    {
        Object finalizerGuardian = new Object() {
            @Override
            protected void finalize() {
                System.out.println("Finalizer guardian finalize");
                Super.this.finalize();
            }
        };
    }

    protected void finalize() {
        System.out.println("Super finalize");
    }

}
下面是一个示例子类--

当s1对象超出范围时,将调用终结器guardian的finalize(),我从子类的finalize方法中获取SYSO,但从未从super的finalize中获取SYSO

我很困惑。我从根本上误解了什么吗


免责声明:我意识到终结器是危险的,不可取,等等。我仍在试图理解这里的问题

高效Java的终结器守护者应该自己执行必要的终结逻辑(例如,调用执行实际终结的
Super
方法),而不是调用
finalize()
方法,因为在您的情况下
Super.this.finalize()
实际上从子类调用重写的方法

还要注意,终结器guardian应该是类的一个字段:

public class Super {
    private final Object finalizerGuardian = new Object() {
            @Override
            protected void finalize() {
                Super.this.doFinalize();
            }
    };

    private void doFinalize() {
        System.out.println("Super finalize");
    }
}

您正在重载
Sub
中的
Super.finalize()
方法。这就是为什么没有人叫它


因此,当您在“
finalizerGuardian
”中调用
Super.this.finalize()
您实际上正在调用
Sub.finalize()

,因为其他人已经说过动态调度是您的问题。但据我所知,代码中还有一个主要缺陷:finalizerGuardian仅在初始化块中定义,这意味着一旦对象初始化,对象就会超出范围,可以进行gcd

Ie即使您解决了第一个问题(通过在类中定义一个处理终结内容的final方法),您仍然需要将finalizerGuardian保存在一个实例变量中。

Super.finalize()
不会被调用,因为Sub会覆盖它。尝试添加一个
Super.\u finalize()
方法,并从
Super.finalize()
和终结器调用它

另外,我认为
finalizerGuardian
需要是
Super
的一个字段。否则,即使超级对象仍然是强可访问的,它也会被垃圾收集。

陷入“它不工作”的困境,看不到明显的问题。谢谢
public class Super {
    private final Object finalizerGuardian = new Object() {
            @Override
            protected void finalize() {
                Super.this.doFinalize();
            }
    };

    private void doFinalize() {
        System.out.println("Super finalize");
    }
}