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 开发者_JAVA百科scenario ?
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.
You should always call super.finalize()
to prevent resource leak. See this and this. Garbage collector will always call finalize()
at most once and due to polymorphism, only the overriden method is called explicitly.
Note that it is even advisable to call finalize()
inside finally
to make sure it is called. But I will give you even better advice: don't depend on finalize
at all. Close your resources explicitly as fast as you can and try new Java 7 feature: try with resource.
No, only B
's finalize method will be called if you do not explicitly use super.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.
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.
精彩评论