我一直在阅读很多关于finalize()的Java新手问题,并发现没有人真正清楚地表明finalize()是一种不可靠的清理资源的方法,这有点令人困惑。我看到有人评论说他们用它来清理连接,这真的很可怕,因为唯一接近于保证连接关闭的方法是最后实现try (catch)。
我没有学过CS,但我已经用Java专业编程近十年了,我从来没有见过有人在生产系统中实现finalize()。这并不意味着它没有用处,或者和我一起工作的人一直在做正确的事情。
所以我的问题是,实现finalize()有哪些用例不能通过语言中的另一个进程或语法更可靠地处理?
请提供具体的场景或您的经验,简单地重复Java教科书,或最终确定的预期用途是不够的,因为这不是这个问题的意图。
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方法中使一个不可达的实例可达。
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方法中使一个不可达的实例可达。
资源(文件,套接字,流等)需要关闭一旦我们完成他们。它们通常有close()方法,我们通常在try-catch语句的finally部分调用该方法。有时finalize()也可以被少数开发人员使用,但在我看来,这不是一种合适的方式,因为不能保证finalize总是被调用。
在Java 7中,我们有try-with-resources语句,可以这样使用:
try (BufferedReader br = new BufferedReader(new FileReader(path))) {
// Processing and other logic here.
} catch (Exception e) {
// log exception
} finally {
// Just in case we need to do some stuff here.
}
在上面的例子中,try-with-resource将通过调用close()方法自动关闭资源BufferedReader。如果我们愿意,我们也可以在自己的类中实现Closeable,并以类似的方式使用它。在我看来,这似乎更整洁,更容易理解。