我一直在阅读很多关于finalize()的Java新手问题,并发现没有人真正清楚地表明finalize()是一种不可靠的清理资源的方法,这有点令人困惑。我看到有人评论说他们用它来清理连接,这真的很可怕,因为唯一接近于保证连接关闭的方法是最后实现try (catch)。
我没有学过CS,但我已经用Java专业编程近十年了,我从来没有见过有人在生产系统中实现finalize()。这并不意味着它没有用处,或者和我一起工作的人一直在做正确的事情。
所以我的问题是,实现finalize()有哪些用例不能通过语言中的另一个进程或语法更可靠地处理?
请提供具体的场景或您的经验,简单地重复Java教科书,或最终确定的预期用途是不够的,因为这不是这个问题的意图。
就我个人而言,除了在一种罕见的情况下,我几乎从不使用finalize():我创建了一个自定义泛型类型集合,并编写了一个自定义finalize()方法,它执行以下操作:
public void finalize() throws Throwable {
super.finalize();
if (destructiveFinalize) {
T item;
for (int i = 0, l = length(); i < l; i++) {
item = get(i);
if (item == null) {
continue;
}
if (item instanceof Window) {
((Window) get(i)).dispose();
}
if (item instanceof CompleteObject) {
((CompleteObject) get(i)).finalize();
}
set(i, null);
}
}
}
(CompleteObject是我做的一个接口,让你指定你已经实现了很少实现的对象方法,如#finalize(), #hashCode()和#clone()))
因此,使用姐妹方法# setdestructivelyfinalizer(布尔值),使用我的集合的程序可以(帮助)确保销毁对该集合的引用也会销毁对其内容的引用,并处理可能在无意中保持JVM活动的任何窗口。我也考虑过停止任何线程,但这打开了一个全新的蠕虫罐头。
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():我创建了一个自定义泛型类型集合,并编写了一个自定义finalize()方法,它执行以下操作:
public void finalize() throws Throwable {
super.finalize();
if (destructiveFinalize) {
T item;
for (int i = 0, l = length(); i < l; i++) {
item = get(i);
if (item == null) {
continue;
}
if (item instanceof Window) {
((Window) get(i)).dispose();
}
if (item instanceof CompleteObject) {
((CompleteObject) get(i)).finalize();
}
set(i, null);
}
}
}
(CompleteObject是我做的一个接口,让你指定你已经实现了很少实现的对象方法,如#finalize(), #hashCode()和#clone()))
因此,使用姐妹方法# setdestructivelyfinalizer(布尔值),使用我的集合的程序可以(帮助)确保销毁对该集合的引用也会销毁对其内容的引用,并处理可能在无意中保持JVM活动的任何窗口。我也考虑过停止任何线程,但这打开了一个全新的蠕虫罐头。