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.
Effective Java’s finalizer guardian should perform the necessary finalization logic itself (for example, call some method of
Superthat 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: