package initialization;
class Tank {
static int counter;
int id = counter++;
boolean full;
public Tank() {
System.out.println("Tank " + id + " created");
full = true;
}
public void empty() { full = false; }
protected void finalize() {
if(full)
System.out.println(
"Error: tank " + id + " must be empty at cleanup");
else
System.out.println("Tank " + id + " cleaned up OK");
}
public String toString() { return "Tank " + id; }
}
public class E12_TankWithTerminationCondition {
public static void main(String args[]) {
new Tank().empty();
new Tank();
// Don't empty the second one
System.gc(); // Force finalization?
System.runFinalization();
}
} /* Output:
Tank 0 created
Tank 1 created
Error: tank 1 must be empty at cleanup
Tank 0 cleaned up OK
*///:~
System.gc()是java中的垃圾回收机制,通过该方法调用提醒java虚拟机回收不用的对象,此时虚拟机会调用销毁对象的finalize()方法
finalize在一个类被销毁时执行。new Tank().empty(); new Tank(); 这两行代码创建了两个类,但是都没有赋值或后续都不再使用到,所以会被垃圾回收器回收掉,这时就会调用finalize了。按照你finalize中的代码,打印出了信息。tank 1虽然说打印出了error,但是仅仅是打印,打印完该对象还是被清理掉了。
finalize方法是在垃圾回收器清理对象占用内存之前执行的,调用gc,执行finalize,此时对象仍然存在,所以full=true,会打印出id=1;gc只是通知垃圾回收器进行垃圾回收,但是实际垃圾回收的时间并不确定,就跟去餐馆吃饭一样,你通知服务员来收拾上一波客人留下的盘子,但是服务员可能立马就来了,也可能好半天才来,时间并不确定,runFinalization打印了id=0,说明之前gc已清理了对象