关于finalize方法的问题,求解释代码

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已清理了对象