爪哇
在 Java 中,有一个成语叫做“ Finalizer Guardian ”,它可以防止子类覆盖超类的终结器但忘记调用它。这是来自Effective Java Item7的示例:
// Finalizer Guardian idiom
public class Foo {
// Sole purpose of this object is to finalize outer Foo object
private final Object finalizerGuardian = new Object() {
@Override protected void finalize() throws Throwable {
... // Finalize outer Foo object
}
};
... // Remainder omitted
}
使用这种技术,即使具有终结器的子类不调用超类的终结器,私有对象也会运行超类的终结代码。
C#
但是,在C# in a Nutshell中的“从终结器调用 Dispose ”部分中,有一个这样的示例:
class Test : IDisposable {
public void Dispose() // NOT virtual {
Dispose (true);
GC.SuppressFinalize (this); // Prevent finalizer from running.
}
protected virtual void Dispose (bool disposing) {
if (disposing) {
// Call Dispose() on other objects owned by this instance.
// You can reference other finalizable objects here.
// ...
}
// Release unmanaged resources owned by (just) this object.
// ...
}
˜Test() {
Dispose (false);
}
}
作者还表示:
该
disposing
标志意味着它是从Dispose
方法中“正确”调用的,而不是在终结器中的“最后手段模式”中。这个想法是,当使用disposing
set to调用时false
,此方法通常不应使用终结器引用其他对象(因为这些对象本身可能已被终结,因此处于不可预测的状态)
问题
但是,当我们回顾 Java 的 Finalizer Guardian 习语时,内部私有的 Guardian 对象实际上是在引用/终结外部对象,而外部对象本身可能具有终结器。它违反了C# in a Nutshell的作者所说的。
我很好奇为什么“在终结器中引用其他可终结对象”在 Java 中是可能的,但在 C# 中却不行。谢谢回答。