通常,你不能指望finalize( ),你必须创建其它的“清除”方法,并且明确地调用它们。看来,
finalize( )只能存在于程序员很难用到的一些晦涩用法里了。不过,finalize( )还有一个有趣的
用法,它并不依赖于每次都要对finalize( )进行调用,这就是对象“终结条件”5的验证。
当你对某个对象不再感兴趣,也就是它可以被清除时,这个对象应该处于某种状态,使它占
用的内存可以被安全地释放。例如,要是对象代表了一个打开的文件,在对象被回收前程序
员应该关闭这个文件。只要对象中存在没有被适当清除的部分,你的程序就存在很隐晦的错
误。finalize( )的价值在于可以用来最终发现这种情况,尽管它并不总是会被调用。如果某次
finalize( )的动作使得 bug 被发现,那你就可据此找出问题所在——这才是你真正关心的。
以下是个简单的例子,示范了可能的使用方式:
//: c04:TerminationCondition.java
// Using finalize() to detect an object that
// hasn't been properly cleaned up.
import com.bruceeckel.simpletest.*;
class Book {
boolean checkedOut = false;
Book(boolean checkOut) {
checkedOut = checkOut;
}
void checkIn() {
checkedOut = false;
}
public void finalize() {
if(checkedOut)
System.out.println("Error: checked out");
}
}
public class TerminationCondition {
static Test monitor = new Test();
public static void main(String[] args) {
Book novel = new Book(true);
// Proper cleanup:
novel.checkIn();
// Drop the reference, forget to clean up:
new Book(true);
// Force garbage collection & finalization:
System.gc();
monitor.expect(new String[] {
"Error: checked out"}, Test.WAIT);
}
} ///:~
本例的终结条件是:所有的 Book 对象在被当作垃圾回收前都应该被签入(check in)。但在
main( )方法中,由于程序员的错误,有一本书未被签入。要是没有 finalize( )来验证终结条
件,将很难发现这种错误。
注意,System.gc( )用于强制终结动作的进行(在写程序的时候这么做可以加速调试过程)。
即使不这么做的话,通过重复的执行程序(假设程序将分配大量的存储空间而导致垃圾回收
finalize( )只能存在于程序员很难用到的一些晦涩用法里了。不过,finalize( )还有一个有趣的
用法,它并不依赖于每次都要对finalize( )进行调用,这就是对象“终结条件”5的验证。
当你对某个对象不再感兴趣,也就是它可以被清除时,这个对象应该处于某种状态,使它占
用的内存可以被安全地释放。例如,要是对象代表了一个打开的文件,在对象被回收前程序
员应该关闭这个文件。只要对象中存在没有被适当清除的部分,你的程序就存在很隐晦的错
误。finalize( )的价值在于可以用来最终发现这种情况,尽管它并不总是会被调用。如果某次
finalize( )的动作使得 bug 被发现,那你就可据此找出问题所在——这才是你真正关心的。
以下是个简单的例子,示范了可能的使用方式:
//: c04:TerminationCondition.java
// Using finalize() to detect an object that
// hasn't been properly cleaned up.
import com.bruceeckel.simpletest.*;
class Book {
boolean checkedOut = false;
Book(boolean checkOut) {
checkedOut = checkOut;
}
void checkIn() {
checkedOut = false;
}
public void finalize() {
if(checkedOut)
System.out.println("Error: checked out");
}
}
public class TerminationCondition {
static Test monitor = new Test();
public static void main(String[] args) {
Book novel = new Book(true);
// Proper cleanup:
novel.checkIn();
// Drop the reference, forget to clean up:
new Book(true);
// Force garbage collection & finalization:
System.gc();
monitor.expect(new String[] {
"Error: checked out"}, Test.WAIT);
}
} ///:~
本例的终结条件是:所有的 Book 对象在被当作垃圾回收前都应该被签入(check in)。但在
main( )方法中,由于程序员的错误,有一本书未被签入。要是没有 finalize( )来验证终结条
件,将很难发现这种错误。
注意,System.gc( )用于强制终结动作的进行(在写程序的时候这么做可以加速调试过程)。
即使不这么做的话,通过重复的执行程序(假设程序将分配大量的存储空间而导致垃圾回收
动作的执行),最终还是很有可能找出错误的 Book 对象的。