使用gc()方法后不调用Java finalize()方法?

时间:2016-07-17 10:43:48

标签: java

要查看当对象即将被销毁时调用的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()方法。

2 个答案:

答案 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案例,因此您的类应该被命名为CounterTestFinalize