程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> java繼承和finalize()

java繼承和finalize()

編輯:關於JAVA

通過“合成”方法創建新類時,永遠不必擔心對那個類的成員對象的收尾工作。每個成員都是一個獨立的對象,所以會得到正常的垃圾收集以及收尾處理——無論它是不是不自己某個類一個成員。但在進行初始化的時候,必須覆蓋衍生類中的finalize()方法——如果已經設計了某個特殊的清除進程,要求它必須作為垃圾收集的一部分進行。覆蓋衍生類的finalize()時,務必記住調用finalize()的基礎類版本。否則,基礎類的初始化根本不會發生。下面這個例子便是明證:
 

//: Frog.java
// Testing finalize with inheritance

class DoBaseFinalization {
  public static boolean flag = false;
}

class Characteristic {
  String s;
  Characteristic(String c) {
    s = c;
    System.out.println(
      "Creating Characteristic " + s);
  }
  protected void finalize() {
    System.out.println(
      "finalizing Characteristic " + s);
  }
}

class LivingCreature {
  Characteristic p = 
    new Characteristic("is alive");
  LivingCreature() {
    System.out.println("LivingCreature()");
  }
  protected void finalize() {
    System.out.println(
      "LivingCreature finalize");
    // Call base-class version LAST!
    if(DoBaseFinalization.flag)
      try {
        super.finalize();
      } catch(Throwable t) {}
  }
}

class Animal extends LivingCreature {
  Characteristic p = 
    new Characteristic("has heart");
  Animal() {
    System.out.println("Animal()");
  }
  protected void finalize() {
    System.out.println("Animal finalize");
    if(DoBaseFinalization.flag)
      try {
        super.finalize();
      } catch(Throwable t) {}
  }
}

class Amphibian extends Animal {
  Characteristic p = 
    new Characteristic("can live in water");
  Amphibian() {
    System.out.println("Amphibian()");
  }
  protected void finalize() {
    System.out.println("Amphibian finalize");
    if(DoBaseFinalization.flag)
      try {
        super.finalize();
      } catch(Throwable t) {}
  }
}

public class Frog extends Amphibian {
  Frog() {
    System.out.println("Frog()");
  }
  protected void finalize() {
    System.out.println("Frog finalize");
    if(DoBaseFinalization.flag)
      try {
        super.finalize();
      } catch(Throwable t) {}
  }
  public static void main(String[] args) {
    if(args.length != 0 && 
       args[0].equals("finalize"))
       DoBaseFinalization.flag = true;
    else
      System.out.println("not finalizing bases");
    new Frog(); // Instantly becomes garbage
    System.out.println("bye!");
    // Must do this to guarantee that all 
    // finalizers will be called:
    System.runFinalizersOnExit(true);
  }
} ///:~


DoBasefinalization類只是簡單地容納了一個標志,向分級結構中的每個類指出是否應調用super.finalize()。這個標志的設置建立在命令行參數的基礎上,所以能夠在進行和不進行基礎類收尾工作的前提下查看行為。
分級結構中的每個類也包含了Characteristic類的一個成員對象。大家可以看到,無論是否調用了基礎類收尾模塊,Characteristic成員對象都肯定會得到收尾(清除)處理。
每個被覆蓋的finalize()至少要擁有對protected成員的訪問權力,因為Object類中的finalize()方法具有protected屬性,而編譯器不允許我們在繼承過程中消除訪問權限(“友好的”比“受到保護的”具有更小的訪問權限)。
在Frog.main()中,DoBaseFinalization標志會得到配置,而且會創建單獨一個Frog對象。請記住垃圾收集(特別是收尾工作)可能不會針對任何特定的對象發生,所以為了強制采取這一行動,System.runFinalizersOnExit(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++中用於“破壞器”相同的形式,我們應該首先執行衍生類的收尾,再是基礎類的收尾。這是由於衍生類的收尾可能調用基礎類中相同的方法,要求基礎類組件仍然處於活動狀態。因此,必須提前將它們清除(破壞)。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved