通过合成方法创建新类时永远不必担心对那个类的成员对象的收尾工作每个成员都是一个独立的对象所以会得到正常的垃圾收集以及收尾处理——无论它是不是不自己某个类一个成员但在进行初始化的时候必须覆盖衍生类中的finalize()方法——如果已经设计了某个特殊的清除进程要求它必须作为垃圾收集的一部分进行覆盖衍生类的finalize()时务必记住调用finalize()的基础类版本否则基础类的初始化根本不会发生下面这个例子便是明证 //: Frogjava // Testing finalize with inheritance class DoBaseFinalization { public static boolean flag = false; } class Characteristic { String s; Characteristic(String c) { s = c; Systemoutprintln( Creating Characteristic + s); } protected void finalize() { Systemoutprintln( finalizing Characteristic + s); } } class LivingCreature { Characteristic p = new Characteristic(is alive); LivingCreature() { Systemoutprintln(LivingCreature()); } protected void finalize() { Systemoutprintln( LivingCreature finalize); // Call baseclass version LAST! if(DoBaseFinalizationflag) try { superfinalize(); } catch(Throwable t) {} } } class Animal extends LivingCreature { Characteristic p = new Characteristic(has heart); Animal() { Systemoutprintln(Animal()); } protected void finalize() { Systemoutprintln(Animal finalize); if(DoBaseFinalizationflag) try { superfinalize(); } catch(Throwable t) {} } } class Amphibian extends Animal { Characteristic p = new Characteristic(can live in water); Amphibian() { Systemoutprintln(Amphibian()); } protected void finalize() { Systemoutprintln(Amphibian finalize); if(DoBaseFinalizationflag) try { superfinalize(); } catch(Throwable t) {} } } public class Frog extends Amphibian { Frog() { Systemoutprintln(Frog()); } protected void finalize() { Systemoutprintln(Frog finalize); if(DoBaseFinalizationflag) try { superfinalize(); } catch(Throwable t) {} } public static void main(String[] args) { if(argslength != && args[]equals(finalize)) DoBaseFinalizationflag = true; else Systemoutprintln(not finalizing bases); new Frog(); // Instantly becomes garbage Systemoutprintln(bye!); // Must do this to guarantee that all // finalizers will be called: SystemrunFinalizersOnExit(true); } } ///:~ DoBasefinalization类只是简单地容纳了一个标志向分级结构中的每个类指出是否应调用superfinalize()这个标志的设置建立在命令行参数的基础上所以能够在进行和不进行基础类收尾工作的前提下查看行为 分级结构中的每个类也包含了Characteristic类的一个成员对象大家可以看到无论是否调用了基础类收尾模块Characteristic成员对象都肯定会得到收尾(清除)处理 每个被覆盖的finalize()至少要拥有对protected成员的访问权力因为Object类中的finalize()方法具有protected属性而编译器不允许我们在继承过程中消除访问权限(友好的比受到保护的具有更小的访问权限) 在Frogmain()中DoBaseFinalization标志会得到配置而且会创建单独一个Frog对象请记住垃圾收集(特别是收尾工作)可能不会针对任何特定的对象发生所以为了强制采取这一行动SystemrunFinalizersOnExit(true)添加了额外的开销以保证收尾工作的正常进行若没有基础类初始化则输出结果是 not finalizing bases Creating Characteristic is alive LivingCreature() Creating Characteristic has heart Animal() Creating Characteristic can live in water Amphibian() Frog() bye! Frog finalize finalizing Characteristic is alive finalizing Characteristic has heart finalizing Characteristic can live in water 从中可以看出确实没有为基础类Frog调用收尾模块但假如在命令行加入finalize自变量则会获得下述结果 Creating Characteristic is alive LivingCreature() Creating Characteristic has heart Animal() Creating Characteristic can live in water Amphibian() Frog() bye! Frog finalize Amphibian finalize Animal finalize LivingCreature finalize finalizing Characteristic is alive finalizing Characteristic has heart finalizing Characteristic can live in water 尽管成员对象按照与它们创建时相同的顺序进行收尾但从技术角度说并没有指定对象收尾的顺序但对于基础类我们可对收尾的顺序进行控制采用的最佳顺序正是在这里采用的顺序它与初始化顺序正好相反按照与C++中用于破坏器相同的形式我们应该首先执行衍生类的收尾再是基础类的收尾这是由于衍生类的收尾可能调用基础类中相同的方法要求基础类组件仍然处于活动状态因此必须提前将它们清除(破坏) |