假设我有以下课程
class A {
//some attributes
@override
protected void finalize() throws Throwable {
//do something
}
}
class B extends A {
@override
protected void finalize() throws Throwable {
//DONT call super.finalize()
//do something
}
}
在这种情况下会发生什么?在某些时候,垃圾收集器是否会调用调用A类的finalize方法?
调用它与在子类的finalize方法中调用A的finalize方法之间有什么不同,如果垃圾收集器无论如何都要调用它?
在什么情况下,可以不在子类中调用其父级的finalize方法?这种情况的任何一个例子?
答案 0 :(得分:2)
首先,显式调用finalize()方法就像调用任何其他Java方法一样。如果您的特定类覆盖了finalize()
方法,那么永远不会确定不调用父级的finalize()方法。当然,如果实现finalizer guardian pattern,则不需要在子类中显式调用父终结器。
finalize()
方法来清理可以明确清除的资源(比如关闭文件句柄等),因为终结器是非确定性的。另外,请查看presentation by Bob Lee以使用Phantom引用代替终结器。
答案 1 :(得分:2)
您应该始终致电super.finalize()
以防止资源泄漏。请参阅this和this。垃圾收集器总是最多调用finalize()
一次,由于多态性,只显式调用overriden方法。
请注意,甚至建议在finalize()
内调用finally
以确保调用它。但我会给你更好的建议:完全不依赖finalize
。尽快显式关闭资源并尝试新的Java 7功能:try with resource。
答案 2 :(得分:1)
不,如果您没有像任何其他方法调用一样明确使用B
,则只会调用super.finalize()
的finalize方法。
但是你应该注意,不调用超类的finalize方法不是一个好习惯。您可能会无意中错过关闭资源或其他内容。
答案 3 :(得分:1)
回答你的问题,
垃圾收集器会在某个时间点调用finalize()方法,但这不能保证。
垃圾收集只会在当前对象上调用finalize()。所以在B上调用finalize()不会在A上调用finalize(),除非使用super.finalize()显式调用。
finalize()方法。现在如果A和B有不同的finalize方法实现,并且B的终结不依赖于那么你不应该调用parent finalize方法。 例如,A的finalize()方法释放某些资源,专门的B类也释放某些资源(独立于As)。以类似的方式,可能有其他A的子类正在使用A的资源(因此不会覆盖A的finalize())。在这种情况下,如果从B.finalize调用super.finalize(),可能会导致麻烦,因为A持有的资源被其他子类使用。