[英]Java finalizer guardian does not seem to work?
我有一個帶有 finalize() 方法的伸縮構造函數的超級 class。 為了防止子類忘記調用 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 object 超出 scope 時,終結器監護人的 finalize() 被調用,我從子類的 finalize 方法中獲取 SYSO,但從未從 super 的 finalize 中獲取。
我很困惑。 我從根本上誤解了什么嗎?
免責聲明:我意識到終結器是危險的,不可取的,等等。仍然試圖理解這里的問題。
有效的 Java 終結器監護人應該自己執行必要的終結邏輯(例如,調用Super
的某些方法來執行實際終結)而不是調用finalize()
方法,因為在你的情況下Super.this.finalize();
實際上是從子類調用被覆蓋的方法。
另請注意,終結器監護人應該是 class 的字段:
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 僅在初始化塊內定義,這意味着一旦 object 初始化,object 就會退出 Z31A1FD140BE4BEF2D11E181ECGCA9 和 be21ECGC9。
即即使你解決了你的第一個問題(通過在你的 class 中定義一個處理終結的東西的最終方法),你仍然需要將 finalizerGuardian 保存在一個實例變量中。
Super.finalize()
沒有被調用,因為 Sub 覆蓋它。 嘗試添加一個Super._finalize()
方法並從Super.finalize()
和終結器監護人調用它。
另外,我認為finalizerGuardian
需要是Super
的一個字段。 否則,即使 Super object 仍然是強可達的,它也會被垃圾收集。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.