|
发表于 2004-7-2 13:28:37
|
显示全部楼层
第6条:避免使用终结函数
Item 6: Avoid finalizers
终结函数(finalizer)通常是不可预测的,常常也是很危险的,一般情况下是不必要的。使用终结函数会导致不稳定的行为、更差的性能,以及带来移植问题。
Finalizers are unpredictable, often dangerous, and generally unnecessary. Their use can cause erratic behavior, poor performance, and portability problems.
JLS不仅不保证终结函数被及时地执行,而且根本不保证它们会被执行。因此,时间关键(time-critical)的任务不应该由终结函数完成(如文件资源的归还),我们也不应该依赖一个终结函数来更新关键性的永久状态(如共享资源的永久锁)。另外,当终结函数的执行时抛出异常时,问题会更严重。
There is no guarantee that finalizers will be executed promptly [JLS, 12.6]. It can take arbitrarily long between the time that an object becomes unreachable and the time that its finalizer is executed.This means that nothing time-critical should ever be done by a finalizer.
如果确实有资源要回收则不想使用终结函数,办法是提供一个显式的终止方法。显式的终止方法通常与try-finally结构配合使用,以确保及时终止。
Explicit termination methods are often used in combination with the try-finally
construct to ensure prompt termination.
当然,终结函数并非一无是处:第一种用途是当一个对象的所有者忘记了调用建议的显式终止方法时,终结函数可以充当“安全网(safety net)”。第二种用途与对象的本地对等体(native peer)有关。本地对等体是一个本地对象,普通对象通过本地方法(native method)委托给一个本地对象。因为本地对等体不是一个普通对象,所以垃圾回收器不会知道它,当它的普通对等体被回收的时候,它不会被回收。在本地对等体不拥有关键资源的前提下,终结函数是执行这项任务的最合适的工具。
So what, if anything, are finalizers good for? There are two legitimate uses. One is to act as a “safety net” in case the owner of an object forgets to call the explicit termination method that you provided per the advice in the previous paragraph.A second legitimate use of finalizers concerns objects with native peers. A native peer is anative object to which a normal object delegates via native methods.
使用终结函数时,“终结函数链(finalizer chain)”并不会被自动执行,因而子类的终结函数必须手工调用超类的终结函数。
It is important to note that “finalizer chaining” is not performed automatically.
如:
//manual finalizer chaining
protected void finalize() throws Trowable{
try{
//Finalize subclass state
...
}finally{
super.finalize();
}
}
可以通过使用匿名类来实现“终结函数守卫者(finalizer guardian)”,以确保子类和超类的终结函数都被调用。参见第18条。
A single instance of the anonymous class, called a finalizer guardian, is created for each instance of the enclosing class. |
|