class DoBaseFinalization { 
public static boolean flag=false; 
} class Base { 
Base() { 
System.out.println("Base()"); 

protected void finalize() throws Throwable { 
System.out.println("Base finalized()!"); 
if(DoBaseFinalization.flag) 
super.finalize(); 

} class Second extends Base { 
Second() { 
System.out.println("Second()"); 

protected void finalize() throws Throwable { 
System.out.println("Second finalized()!"); 
if(DoBaseFinalization.flag) 
super.finalize(); 

} class Third extends Second { 
Third() { 
System.out.println("Third()"); 

protected void finalize() throws Throwable { 
System.out.println("Third finalized()!"); 
if(DoBaseFinalization.flag) 
super.finalize(); 

} public class C07_11 { 
public static void main(String[] args) { 
if((args.length!=0)&&(args[0].equals("finalize"))) 
DoBaseFinalization.flag=true; 
else 
System.out.println("Not Finalized!"); 
//new Third(); 
System.out.println("Bye!"); 
System.gc(); 

} 这是一个子类都能正确呼叫base class的finalize的例子,上面这段标记的地方如果用Third td=new Third(),那么就算引数输入finalize,也不能呼叫finalize的方法,一定要使用new Third(),我不知道为什么?请各位高手赐教阿!!!

解决方案 »

  1.   

    当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。子类重写 finalize 方法,以配置系统资源或执行其他清除。 
    finalize 的常规协定是:当 JavaTM 虚拟机已确定尚未终止的任何线程无法再通过任何方法访问此对象时,将调用此方法,除非由于准备终止的其他某个对象或类的终结操作执行了某个操作。finalize 方法可以采取任何操作,其中包括再次使此对象对其他线程可用;不过,finalize 的主要目的是在不可撤消地丢弃对象之前执行清除操作。例如,表示输入/输出连接的对象的 finalize 方法可执行显式 I/O 事务,以便在永久丢弃对象之前中断连接。 Object 类的 finalize 方法执行非特殊性操作;它仅执行一些常规返回。Object 的子类可以重写此定义。 Java 编程语言不保证哪个线程将调用某个给定对象的 finalize 方法。但可以保证在调用 finalize 时,调用 finalize 的线程将不会持有任何用户可见的同步锁定。如果 finalize 方法抛出未捕获的异常,那么该异常将被忽略,并且该对象的终结操作将终止。 在启用某个对象的 finalize 方法后,将不会执行进一步操作,直到 Java 虚拟机再次确定尚未终止的任何线程无法再通过任何方法访问此对象,其中包括由准备终止的其他对象或类执行的可能操作,在执行该操作时,对象可能被丢弃。 对于任何给定对象,Java 虚拟机最多只调用一次 finalize 方法。 finalize 方法抛出的任何异常都会导致此对象的终结操作停止,但可以通过其他方法忽略它。 
      

  2.   

    不用,你这个程序是可以调用子类的finalize方法的,我试了可以调用。
    只有当对象不被调用时才能调用对象的finalize方法
      

  3.   

    用new Third();的时候,首先生成一个对象,然后给它赋给一个临时变量,因为下一条语句以后,已经没有一个引用继续引用这个对象,所以当垃圾回收被执行的时候,这个对象就被回收,finalize方法也就被调用。
    而用Third td = new Third()的时候,首先生成一个对象,然后给它赋给一个变量td,这个td的生命周期是main方法中,也就是main方法不结束,td一直活着,也就是td一直引用new Third()生成的对象,所以直到main方法结束,td才被回收,而main方法结束,程序也就退出了,所以就看不到finalize了。
    你把Third td = new Third()改成{Third td = new Third();},加上个花括号,估计就能看到finalize了。这里面涉及到一个对象生命周期的问题,生命没结束,就不会被回收。