Java终结器守护者似乎不起作用?
我有一个带有带有 Finalize() 方法的伸缩构造函数的超类。为了防止子类忘记调用 super.finalize,我编写了一个终结器守护程序(EJ Item 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");
}
}
这是一个示例子类——
public class Sub extends Super {
public Sub() {}
protected void finalize() {
System.out.println("Sub finalize");
}
public static void main(String[] args)
throws InterruptedException {
if (1 == 1) {
Sub s1 = new Sub();
}
Runtime.getRuntime().gc();
Thread.sleep(10000);
}
}
当 s1 对象超出范围时,终结器守护者的 Finalize() 被调用,我从子类的 Finalize 方法中获取 SYSO,但永远不会从超级的 Finalize 中获取 SYSO。
我很困惑。我是否从根本上误解了某些东西?
免责声明:我意识到终结器是危险的并且不可取,等等。仍在尝试理解这里的问题。
I have a super class with telescoping constructors with a finalize() method. To protect against subclasses forgetting to invoke super.finalize, I have written a finalizer guardian (EJ Item 7 ) like so.
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");
}
}
Here is a sample subclass --
public class Sub extends Super {
public Sub() {}
protected void finalize() {
System.out.println("Sub finalize");
}
public static void main(String[] args)
throws InterruptedException {
if (1 == 1) {
Sub s1 = new Sub();
}
Runtime.getRuntime().gc();
Thread.sleep(10000);
}
}
When the s1 object goes out of scope, the finalizer guardian's finalize() gets called, and I get the SYSO from the subclass's finalize method, but never get the one from super's finalize.
I'm confused. Am I misunderstanding something fundamentally?
Disclaimer : I realize finalizers are dangerous and not advisable, etc. Still trying to understand the problem here.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
有效的 Java 终结器守护者应该自行执行必要的终结逻辑(例如,调用执行实际终结的
Super
的某个方法),而不是调用finalize()
方法,因为在您的情况下Super.this.finalize();
实际上从子类调用重写方法。另请注意,终结器监护人应该是该类的一个字段:
Effective Java's finalizer guardian should perform the necessary finalization logic itself (for example, call some method of
Super
that performs the actual finalization) rather than call thefinalize()
method, because in your caseSuper.this.finalize();
actually calls the overriden method from the subclass.Also note that finalizer guardian should be a field of the class:
您正在重载
Sub
中的Super.finalize()
方法。这就是为什么它没有被调用。因此,当您在“
finalizerGuardian
”中调用Super.this.finalize();
时,您实际上是在调用Sub.finalize()
。You are overloading the
Super.finalize()
method inSub
. That's why it's not being called.So when you in "
finalizerGuardian
" callSuper.this.finalize();
you are actually callingSub.finalize()
.正如其他人已经说过的,动态调度是你的问题。但据我所知,您的代码中还有另一个主要错误:您的 FinalizerGuardian 仅在初始化块内定义,这意味着一旦对象被初始化,该对象就会超出范围并可以被 GC 。
即,即使您解决了第一个问题(通过在类中定义处理终结内容的最终方法),您仍然需要将 FinalizerGuardian 保存在实例变量中。
AS others have already said dynamic dispatch is your problem here. BUT there's one other major bug in your code as far as I see: Your finalizerGuardian is only defined inside the initialization block, this means that as soon as the object is initialized, the object gets out of scope and can be GCed.
Ie even if you fix your first problem (by defining a final method in your class that handles the finalization stuff), you'll still need to save the finalizerGuardian in a instance variable.
Super.finalize()
没有被调用,因为 Sub 覆盖了它。尝试添加一个Super._finalize()
方法并从Super.finalize()
和终结器守护程序调用它。另外,我认为 FinalizerGuardian 需要是 Super 的字段。否则,即使超级对象仍然是强可达的,它也会被垃圾收集。
Super.finalize()
is not getting called because Sub overrides it. Try adding aSuper._finalize()
method and calling it fromSuper.finalize()
and the finalizer guardian.Also, I think
finalizerGuardian
needs to be a field ofSuper
. Otherwise, it can get garbage collected even if the Super object is still strongly reachable.