要查看当对象即将被销毁时调用的java中finalize()
方法的工作,我编写了以下程序
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);
}
}
我希望输出像这样
Number of objects :1
Number of objects :2
Program about to terminate
Number of objects :1
Program about to terminate
Number of objects :0
但我刚刚获得前两行。由于我将对象引用为null然后调用gc()
方法,因此我希望应该显示在finalize()
方法中编写的语句。这是否意味着无法保证每次使用finalize()
方法时都会调用gc()
方法。
答案 0 :(得分:2)
你的终结方法应该在counterTest中,然后它会"也许"被调用。你从来没有真正创建和#34;最终确定"类。因此,你的终结方法永远不会被执行。
以下是应该按预期运行的更新代码:
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();
}
}
应该注意的是"敲定"方法并不意味着被覆盖,因为它们不可靠。你永远不知道垃圾收集器什么时候会收集一个特定的对象,所以转发它来关闭你的数据库连接或做其他类似的东西是不,不,不...
答案 1 :(得分:2)
首先,您的代码没有finalize
类的实例(AKA对象)。 main
方法是静态的,没有实例。
但即使你确实有一个实例,在Java GC中调用finalize()
方法也不是很确定或保证。它不是类似于C ++的析构函数。因此,即使您将finalize()
方法添加到counterTest
类,您创建了一些实例,也无法保证它会被调用。
如果您想要与析构函数一样的行为,则需要围绕try-with-resources模式设计代码。然后AutoCloseable
interface's close()
method扮演析构函数的角色。
PS。 Java中有一个非常强的约定来使用带有类名的所谓的Pascal案例,因此您的类应该被命名为CounterTest
和Finalize
。