Reputation: 511
To see the working of finalize()
method in java which is called when the object is about to be destroyed, I have wrote the following program
class counterTest{
public static int count;
public counterTest(){
count++;
}
}
public class finalize {
public static void main(String args[]){
counterTest obj1=new counterTest();
System.out.println("Number of objects :" + counterTest.count);
counterTest obj2=new counterTest();
System.out.println("Number of objects :" + counterTest.count);
Runtime rs=Runtime.getRuntime();
obj1=null;
obj2=null;
rs.gc();
}
protected void finalize(){
System.out.println("Program about to terminate");
counterTest.count--;
System.out.println("Number of objects :" + counterTest.count);
}
}
I expected the output to be like this
Number of objects :1
Number of objects :2
Program about to terminate
Number of objects :1
Program about to terminate
Number of objects :0
But I am just getting the first two lines. Since I am making the objects references to null and then calling the gc()
method, I expect that the statements written in inside finalize()
method should be displayed. Does this mean there is no guarantee that finalize()
method will be called each time we have used gc()
method.
Upvotes: 3
Views: 344
Reputation: 9492
Your finalize method should be in the counterTest and then it will "maybe" be invoked. You never really create and instance of the "finalize" class. Therefore your finalize method never have the chance to be executed.
Here is updated code that should work as you expect:
class counterTest{
public static int count;
public counterTest(){
count++;
}
protected void finalize(){
System.out.println("Program about to terminate");
counterTest.count--;
System.out.println("Number of objects :" + counterTest.count);
}
}
public class Finalize {
public static void main(String args[]){
counterTest obj1=new counterTest();
System.out.println("Number of objects :" + counterTest.count);
counterTest obj2=new counterTest();
System.out.println("Number of objects :" + counterTest.count);
Runtime rs=Runtime.getRuntime();
obj1=null;
obj2=null;
rs.gc();
}
}
It should be noted that the "finalize" methods are not meant to be overridden because they are unreliable. You never know when the Garbage collector will collect a particular object so relaying on it to close your database connections or doing other similar stuff is a No, no, no...
Upvotes: 2
Reputation: 62797
First of all, you code does not have an instance (AKA object) of finalize
class. main
method is static and does not have an instance.
But even if you did have an instance, in Java GC and calling finalize()
methods is not very deterministic or guaranteed. It's not a destructor similar to C++. So even if you added finalize()
method to counterTest
class, of which you create some instances, there's no guarantee it'll get called.
If you want similar behavior as you would have with a destructor, you need to design your code around try-with-resources pattern. Then AutoCloseable
interface's close()
method takes the role of destructor.
PS. There is a very strong convention in Java to use so called Pascal case with class names, so your classes should be named CounterTest
and Finalize
.
Upvotes: 2