[英]Question regarding finalizers in Java
假设我有以下课程
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方法吗? 这样的情况有什么例子吗?
首先,显式调用finalize()方法就像调用任何其他Java方法一样。 如果您的特定类覆盖了finalize()
方法,则永远不要不调用父级的finalize()
方法。 当然,如果实现finalizer的守护者模式 ,则无需在子类中显式调用父finalizer。
顺便说一句,因为finalize()
是不确定的,所以不要依赖finalize()
方法来清理可以显式清除的资源(如关闭文件句柄等)。 另外,请看Bob Lee的演示 ,它使用Phantom引用代替了终结器。
您应该始终调用super.finalize()
以防止资源泄漏。 看到这个和这个 。 垃圾回收器将始终最多调用一次finalize()
,由于多态性,只有显式调用的方法才被覆盖。
需要注意的是,即使最好调用finalize()
内finally
以确保它被调用。 但是我会给您更好的建议:完全不依赖于finalize
。 尽可能快地显式关闭资源,然后尝试Java 7的新功能: 尝试使用resource 。
不,如果您不像其他任何方法调用那样显式使用super.finalize()
,则仅将调用B
的finalize方法。
但是,您应该注意,不调用超类的finalize方法不是一个好习惯。 您可能会无意间错过了关闭资源或其他操作的机会。
为了回答您的问题,
垃圾收集器会在某个时间点调用finalize()方法,但这不能保证。
垃圾回收只会在当前对象上调用finalize()。 因此,除非使用super.finalize()显式调用,否则在B上调用finalize()不会在A上调用finalize()。
如果要在垃圾回收之前执行一些清理操作,则调用finalize()方法。 现在,如果A和B的finalize方法的实现方式不同,并且B的finalization不依赖于As,那么您不应调用父代finalize方法。 例如,A的finalize()方法释放某些资源,而专用类B也释放某些资源(独立于As)。 以类似的方式,可能还有A的其他子类正在使用A的资源(因此不会覆盖A的finalize())。 在这种情况下,如果从B.finalize调用super.finalize(),可能会导致麻烦,因为A拥有的资源被其他子类使用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.