在下面的代码段中,永远不会调用finalize()
方法。但是当我将finalize()
替换为close()
中的addShutdownHook
时。 finalize()
方法将被调用。这是一个错误吗?
public class Main {
public Main() {
Runtime.getRuntime().addShutdownHook(
new Thread(
new Runnable() {
public void run() {
try {
finalize();
} catch (Throwable e) {
System.out.println(e);
}
}
})
);
}
public static void main(String[] args) {
System.out.println("Enter main");
Main m = new Main();
m = new Main();
m = null;
System.out.println("Before System.exit(0);");
System.exit(0);
}
protected void finalize() {
System.out.println("Call finalize()");
}
protected void close() {
finalize();
}
}
答案 0 :(得分:3)
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
public void run() {
try {
finalize();
} catch (Throwable e) {
System.out.println(e);
}
}
}));
这会调用匿名finalize
实例的Runnable
方法(它不执行任何操作,因为它是继承的Object#finalize()
),而不是类中定义的实例。您可以使用以下方法调用后者:
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
public void run() {
try {
Main.this.finalize();
} catch (Throwable e) {
System.out.println(e);
}
}
}));
更好的方法是重命名方法以避免覆盖在垃圾收集器检测到对象不再被引用时调用的Object#finalize()
。
另请注意,在您的代码中,您正在注册两个关闭挂钩(构造函数被调用两次),因此方法finalize
将被调用两次。