我一直在阅读很多关于finalize()的Java新手问题,并发现没有人真正清楚地表明finalize()是一种不可靠的清理资源的方法,这有点令人困惑。我看到有人评论说他们用它来清理连接,这真的很可怕,因为唯一接近于保证连接关闭的方法是最后实现try (catch)。

我没有学过CS,但我已经用Java专业编程近十年了,我从来没有见过有人在生产系统中实现finalize()。这并不意味着它没有用处,或者和我一起工作的人一直在做正确的事情。

所以我的问题是,实现finalize()有哪些用例不能通过语言中的另一个进程或语法更可靠地处理?

请提供具体的场景或您的经验,简单地重复Java教科书,或最终确定的预期用途是不够的,因为这不是这个问题的意图。


当前回答

自1998年以来,我一直在从事Java专业工作,但我从未实现过finalize()。一次也没有。

其他回答

class MyObject {
    Test main;

    public MyObject(Test t) {    
        main = t; 
    }

    protected void finalize() {
        main.ref = this; // let instance become reachable again
        System.out.println("This is finalize"); //test finalize run only once
    }
}

class Test {
    MyObject ref;

    public static void main(String[] args) {
        Test test = new Test();
        test.ref = new MyObject(test);
        test.ref = null; //MyObject become unreachable,finalize will be invoked
        System.gc(); 
        if (test.ref != null) System.out.println("MyObject still alive!");  
    }
}

====================================

结果:

This is finalize

MyObject still alive!

=====================================

所以你可以在finalize方法中使一个不可达的实例可达。

Finalize()对于捕获资源泄漏非常有用。如果资源应该关闭,但没有关闭,则将资源未关闭的事实写入日志文件并关闭。通过这种方式,您可以删除资源泄漏,并提供一种方法来知道它已经发生,以便您可以修复它。

我从1.0 alpha 3(1995)开始就一直在用Java编程,我还没有覆盖任何东西的finalize…

自1998年以来,我一直在从事Java专业工作,但我从未实现过finalize()。一次也没有。

作为旁注:

覆盖finalize()的对象由垃圾回收器进行特殊处理。通常,在对象不再在作用域中后,在收集周期中立即销毁对象。但是,可终结对象被移到队列中,在队列中,独立的终结线程将耗尽队列并在每个对象上运行finalize()方法。一旦finalize()方法终止,对象就可以在下一个循环中进行垃圾收集了。

源代码:finalize()在java-9上已弃用

iirc——你可以使用finalize方法作为实现昂贵资源池机制的一种手段——这样它们就不会得到GC了。