finalize()没有被调用

时间:2014-12-16 06:51:07

标签: java finalize

为什么finalize()不在这里被调用。代码已编译并成功运行,但没有任何输出。

package temp;

public class Temp {

    int i;

    Temp(int j) {
        i = j;
    }

    public void finalize() {
        if (i == 10) {
            System.out.println("Finalize called.");
        }
    }

    public static void main(String[] args) {
        Temp obj = new Temp(10);
        System.gc();
    }

}

4 个答案:

答案 0 :(得分:6)

您对System.gc();的调用没有任何区别,因为您的Temp实例有一个引用(obj),因此它不符合垃圾回收的条件。

即使它有资格进行垃圾收集,调用System.gc();也不一定会立即收集所有没有引用它们的对象。

答案 1 :(得分:2)

我正在阅读Effective Java

第7项:避免定型者

  

终结器是不可预测的,通常是危险的   不必要。 - 有效的Java(第50页)

另一个来自pdf。

  

不要被System.gc和System.runFinalization方法所诱惑。   他们可能会增加执行终结者的几率   不保证。声称保证的唯一方法   最终确定是System.runFi-nalizersOnExit及其邪恶的双胞胎,   Runtime.runFinalizersOnExit。这些方法存在致命缺陷   已被弃用[ThreadStop]。

基于此使用System.gc只会增加终结器执行的几率,重要的是使用它不能保证它将运行垃圾收集,它只是建议到jvm。 / p> 另一个。

  

语言规范不仅不能保证   终结者将立即执行;它不能保证   他们将在第二章创造和破坏对象28中被执行   所有。程序终止是完全可能的,甚至可能的   不对某些不再存在的对象执行终结器   可达

答案 2 :(得分:1)

添加obj = null;以使引用为null,然后将调用您的finalize方法。 Thsi再次不是一种保证行为,对我来说,我曾经有两次能够召唤它。

 public static void main(String[] args) {
        Temp obj = new Temp(10);
        obj  = null;
        System.gc();
    }

<强>输出

hi10
Finalize called.

答案 3 :(得分:0)

在创建对象时,构造函数被调用但不是finalize()方法,所以你需要从实例obj和这里引用函数System.gc();没有任何区别或称为方法finalize();