终结函数并不能保证会及时被执行。从一个对象变得不可到达开始,到它的终结函数被执行,这段时间的长度是任意的、不确定的,有时不一定会被执行(gc只会执行一次)。所以,时间关键的任务不应该由终结函数来完成,并且我们不应该依赖一个终结函数来更新关键性的永久状态。
对于抛出的异常,我们最好是都去捕获,当在终结函数中抛出的异常,都会被忽略掉
所以,最好不要使用终结函数。我们可以使用try-finally去显示的去释放资源
但是终结函数有一个用处,可以去终结垃圾回收器无法回收的内存,比如native 方法分配的内存。
当你真的要使用终结函数,如果此子类覆盖了父类的finalize()方法,那么一定要显示调用父类的终结函数,不然父类的终结方法不会被执行
protected void finalize() throws Throwable{ try { }finally { super.finalize(); } }
为了防止忘记显示去执行父类的finalize()方法,可以在子类中定义一个“终结函数守卫者”,通过匿名类实现的,这样就不用覆盖父类的终结函数方法了,避免了忘记显示调用父类终结函数
class Foo{ private final Object finalizerGuardian = new Object(){ protected void finalize() throws Throwable{ } }; }