为什么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();
}
}
答案 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();