关于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方法,那么调用它和不在子类的finalize方法中调用A的finalize方法有什么不同?
在什么情况下,子类中可以不调用父类的finalize方法?这种情况有什么例子吗?
Assume that I have the following class
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
}
}
What will happen in this scenario ? Will calling class A' finalize method will be called by garbage collector at some point?
What is the different between calling it and not calling A's finalize method in the child class' finalize method if it's anyway going to be called by garbage collector ?
In what scenario, it is ok NOT to call its parent's finalize method in the child class? Any example of such a scenario ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
首先,显式调用 Finalize() 方法就像调用任何其他 Java 方法一样。如果您的特定类重写了
finalize()
方法,那么不调用父类的 Finalize() 方法是永远可以的。当然,如果您实现终结器守护者模式,您不需要在子类中显式调用父终结器。顺便说一句,不要依赖于 Finalize() 方法来清理可以显式清除的资源(例如关闭文件句柄等),因为终结器是不确定的。另外,请查看 Bob Lee 的演示文稿 使用幻像引用代替终结器。
First off, explicitly calling a finalize() method is just like calling any other Java method. It is never OK to not call the parent's finalize() method if your specific class is overriding the
finalize()
method. Of course, if you implement the finalizer guardian pattern, you don't need to explicitly call the parent finalizer in your subclass.BTW, don't rely on
finalize()
methods for cleaning up resources which can be cleared explicitly (like closing file handles etc.) since finalizers are non-deterministic. Also, take a look at the presentation by Bob Lee for using Phantom references in place of finalizers.您应该始终调用 super.finalize() 来防止资源泄漏。请参阅 这个和这个。垃圾收集器总是最多调用一次
finalize()
,并且由于多态性,只有被重写的方法被显式调用。请注意,甚至建议在
finally
内调用finalize()
以确保调用它。但我会给你更好的建议:根本不要依赖finalize
。尽快明确关闭资源并尝试新的 Java 7 功能:尝试与资源。You should always call
super.finalize()
to prevent resource leak. See this and this. Garbage collector will always callfinalize()
at most once and due to polymorphism, only the overriden method is called explicitly.Note that it is even advisable to call
finalize()
insidefinally
to make sure it is called. But I will give you even better advice: don't depend onfinalize
at all. Close your resources explicitly as fast as you can and try new Java 7 feature: try with resource.不,如果您没有像任何其他方法调用一样显式使用
super.finalize()
,则只会调用B
的 Finalize 方法。但是您应该注意,不调用超类的 Finalize 方法并不是一个好习惯。您可能会无意中错过关闭资源或其他内容。
No, only
B
's finalize method will be called if you do not explicitly usesuper.finalize()
just like any other method call.However you should note that it's not a good practice to not call the superclass's finalize method. You might inadvertently miss closing a resource or something.
为了回答您的问题,
垃圾收集器将在某个时间点调用 Finalize() 方法,但这并不能保证。
垃圾收集只会对当前对象调用finalize()。因此,在 B 上调用 Finalize() 不会在 A 上调用 Finalize(),除非使用 super.finalize() 显式调用。
如果您想在对象被垃圾收集之前执行一些清理操作,则会调用 Finalize() 方法。现在,如果 A 和 B 有不同的 Finalize 方法实现,并且 B 的 Finalize 不依赖于 As 那么您不应该调用父级 Finalize 方法。
例如,A的finalize()方法释放了某些资源,而专用类B也释放了某些资源(与As无关)。以类似的方式,A 的其他子类可能正在使用 A 的资源(因此不会覆盖 A 的 Finalize())。在这种情况下,如果您从 B.finalize 调用 super.finalize() ,可能会导致问题,因为 A 持有的资源被其他子类使用。
To answer your questions,
Garbage collector will call finalize() method at some point of time but that's not guaranteed.
Garbage collect will call the finalize() only on the current object. So calling finalize() on B will NOT call finalize() on A unless explicitly called using super.finalize().
finalize() method is called in case you want to do some clean up operation before the object is garbage collected. Now if A and B have different implementation of finalize method and B's finalization does not depend on As then you should not call parents finalize method.
For example, A's finalize() method releases certain resources and specialized class B also releases certain resources (independent of As). In the similar way there might other subclasses of A which are using the resources of A (hence not overriding A's finalize()). In this case if you invoke super.finalize() from B.finalize that may cause trouble as the resources held by A are used by other subclasses.