以下示例改编自《Java编程思想》
//: initialization/TerminationCondition.java
// Using finalize() to detect an object that
// hasn't been properly cleaned up.
class Book {
boolean checkedOut = false;
Book(boolean checkOut) {
checkedOut = checkOut;
}
void checkIn() {
checkedOut = false;
}
@Override
protected void finalize() {
try {
if(checkedOut) {
System.out.println("Error: checked out");
}
}finally {
try {
super.finalize();
} catch (Throwable e) {
e.printStackTrace();
}
}
}
}
public class TerminationCondition {
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();
}
} /* Output:
Error: checked out
*///:~
本例的终结条件是:所有的Book对象在被当做垃圾回收前应该处于checkOut==false的状态。这里可以通过finalize()来验证终结条件,发现程序设计中的缺陷。
java.lang.ref.Cleaner和java.lang.ref.PhantomReference提供更灵活和有效的方式,在对象无法再访问时释放资源。
Cleaner示例
import java.lang.ref.Cleaner;
public class CleaningExample implements AutoCloseable {
// A cleaner, preferably one shared within a library
private static final Cleaner cleaner = Cleaner.create();
static class State implements Runnable {
State() {
System.out.println("init");// initialize State needed for cleaning action
}
public void run() {
System.out.println("clean");// cleanup action accessing State, executed at most once
}
}
private final State state;
private final Cleaner.Cleanable cleanable;
public CleaningExample() {
this.state = new State();
this.cleanable = cleaner.register(this, state);
}
public void close() {
cleanable.clean();
}
public static void main(String[] args) {
while(true) {
new CleaningExample();
}
}
}
本例中每次创建对象时,都会打印init;回收对象时,都会打印clean。