在shutdownHook中调用finalize无法正常工作

时间:2015-08-17 18:49:08

标签: java

在下面的代码段中,永远不会调用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();
    }
}

1 个答案:

答案 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将被调用两次。