I new to Java First time I am trying to learn Java . My simple Question is on finalize () method in java.lang.Object. Why I have access to this only protected method in my other class not other protected method .My tutor told me that protected only have scope in its class, same package, and its subclass .Here I read this.
Can someone explain me is there any special case with finalize()method . I have an answer not satisfying why finalize () is protected here My Code is as Follows :
//Creating Package Foo
package Foo;
class A
{
protected finalize()
{
System.out.println("This is finalize method of Class A");
}
}
// Creating Another Pacakage Foo1
package Foo1;
import Foo.*;
class B extends A
{
}
class C extends B
{
}
class D extends C
{
public void foo() {
C ob = new C();
ob = null;
System.gc(); // Why class A finalize() is getting call
}
}
Only in case of finalize () it is getting called, not in another case . ask my tutor he refuse to answer he saying you are doing some mistake i will look but he is not replying me .
Please think of I am bew to java . Maybe I am doing some big mistake.
This works as expected, and I don't think the finalize()
method is treated any differently to any other method in Java. What could be considered a bit different is that the finalize()
method is normally only called by the JVM Garbage Collector itself, as outlined in the JavaDoc:
Called by the garbage collector on an object when garbage collection determines that there are no more references to the object.
Also note that Josh Bloch strongly cautions against the use of finalizers in Effective Java:
Finalizers are unpredictable, often dangerous, and generally unnecessary. Their use can cause erratic behaviour, poor performance, and portability problems. Finalizers have a few valid uses ... but as a rule of thumb you should avoid finalizers.
Consider the following example, which is similar to yours:
A baseclass with an overriden finalize()
method.
public abstract class BaseClass {
@Override
protected void finalize() throws Throwable {
super.finalize();
System.out.println("BaseClass finalisation occured");
}
}
A sub-class which does not override finalize:
public class SubClass extends BaseClass {
public void foo() {
System.out.println("SubClass Foo'd");
}
}
And a driver class with a basic main method to run everything:
public class Driver {
public static void main(String[] args) {
SubClass sc = new SubClass();
sc.foo();
sc = null;
System.gc();
}
}
The output we get is the following:
SubClass Foo'd
BaseClass finalisation occured
What happens with Java method lookup (in very simple terms) is that any method is looked for in the current class, and if not the class hierarchy is climbed until the required method is found. In the above example, when the foo()
method is called on a SubClass
object, the SubClass
class contains the method definition so that implementation is used, and the class hierarchy is not climbed any higher. When the finalize()
method is called (because a System.gc()
has been requested), the method will first be looked for in the SubClass
class, but since that does not contain an implementation of finalize()
its parent (BaseClass
) is searched. BaseClass
does contain an implementation of finalize()
so that is used, and a line is printed to stdout.
Now consider a sub-sub-class which overrides finalize()
again:
public class OverridenSubClass extends SubClass {
@Override
protected void finalize() throws Throwable {
super.finalize();
System.out.println("Overriden finalize called, which calls super's finalize first");
}
}
And a slightly modified Driver
class:
public class Driver {
public static void main(String[] args) {
OverridenSubClass sc = new OverridenSubClass();
sc.foo();
System.out.println(sc.toString());
sc = null;
System.gc();
System.exit(0);
}
}
Which produces the following output:
SubClass Foo'd
finalize.OverridenSubClass@7150bd4d
BaseClass finalisation occured
Overriden finalize called, which calls initial finalize first
Hopefully this is as expected. The only interesting things to note here are that:
toString()
in any of our classes so the Object.toString()
implementation is used.sc
is not what determines the method implementation used - it is the type of the actual object referenced by sc