首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java RTTI 造型前檢查:instanceof、Class 物件與 Java 1.1 isInstance 動態化

     編輯:Java 相關知識

目前已知 RTTI 形式:

  1. 經典造型 (Shape):用 RTTI 確保正確性,失敗拋 ClassCastException
  2. Class 物件:查詢執行期資料

C++ 經典造型不執行 RTTI,僅告訴編譯器視為新型別。Java 執行型別檢查,稱型別安全下溯造型。上溯造型(Circle→Shape)編譯器自動;下溯造型(Shape→Circle)不保證安全,需明確造型。

instanceof 關鍵字

回傳布林值,造型前檢查:

if(x instanceof Dog) ((Dog)x).bark();

無其他型別資訊時極重要,否則得 ClassCastException。

PetCount.java:標記所有物件型別

//: PetCount.java
package c11.petcount; import java.util.*;
class Pet {} class Dog extends Pet {} class Pug extends Dog {}
class Cat extends Pet {} class Rodent extends Pet {} class Gerbil extends Rodent {}
class Hamster extends Rodent {} class Counter { int i; }
public class PetCount {
    static String[] typenames = {"Pet","Dog","Pug","Cat","Rodent","Gerbil","Hamster"};
    public static void main(String[] args) {
        Vector pets = new Vector();
        try {
            Class[] petTypes = { Class.forName("c11.petcount.Dog"), ... };
            for(int i = 0; i < 15; i++)
                pets.addElement(petTypes[(int)(Math.random()*petTypes.length)].newInstance());
        } catch(...) {}
        Hashtable h = new Hashtable();
        for(int i = 0; i < typenames.length; i++) h.put(typenames[i], new Counter());
        for(int i = 0; i < pets.size(); i++) {
            Object o = pets.elementAt(i);
            if(o instanceof Pet) ((Counter)h.get("Pet")).i++;
            if(o instanceof Dog) ((Counter)h.get("Dog")).i++;
            // ... 其餘 instanceof 陳述式 ...
        }
        // ... 輸出統計 ...
    }
} ///:~

Java 1.0 instanceof 僅能與具名型別比較,不可與 Class 物件比較。大量 instanceof 陳述式顯示設計可能有問題。

Java 1.1 改進:類別字面常數與 isInstance()

PetCount2.java:用 Pet.class 等類別字面常數取代 Class.forName(),編譯期檢查、無例外、效率更高。包名會出現在型別名稱中(如 class c11.petcount2.Pet),需額外處理。

PetCount3.java:Class.isInstance(Object) 動態調用 instanceof,消除逐個 instanceof 陳述式:

for (int j = 0; j < petTypes.length; ++j)
    if (petTypes[j].isInstance(o)) {
        String key = petTypes[j].toString();
        ((Counter)h.get(key)).i++;
    }

新增寵物型別只需修改 petTypes 陣列,無需動程式其他部分。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved