终结函数(finalizer)通常是不可预测的,常常也是很危险的,一般情况下不是必要的。使用终结函数会导致不稳定的行为、更差的性能,以及带来移植性问题。不要把终结函数当做C++中的析构函数(destructors)的对应物。
我自己总结了一下这一条的综合性结论是这样的:
1)在涉及使用资源,使用完毕后要释放资源的情形下,首先要用一个显示的方法(应该是私有的)来释放这些资源;
2)在主方法中通过 try-catch-finally 的结构结合起来,try中写正常操作的代码,catch中处理异常,如写Log等,finally中通过调用1)中的显示的资源释放方法来释放资源(使用finally是因为不论成功还是异常都要释放资源)
3)用终结函数作为“安全网”,防止程序员忘记了2)中的“调用1)中的显示的资源释放方法”。这样迟一点释放资源也总比忘记释放要好;
4)进而用“终结守卫者”来代替3)中的终结函数,这样的好处是,如果这个类被子类继承,而子类的终结函数又忘记调用它的父类的终结函数时,如果父类是用“终结守卫者”来代替“终结函数”的话,就不怕子类遗忘此事了,即使子类的终结函数没有调用,父类的“终结守卫着”也会被执行的。
public class Example{
public void doSomething(){
try{
// 打开资源并使用
......
} catch XXXException e {
......
} finally {
release();
}
}
protected void release(){
// 释放资源
.......
}
private final Object finalizerGuardian = new Object(){
protected void finalize() throws Throwable{
release();
}
};
}