目前已知 RTTI 形式:
(Shape):用 RTTI 確保正確性,失敗拋 ClassCastExceptionClass 物件:查詢執行期資料C++ 經典造型不執行 RTTI,僅告訴編譯器視為新型別。Java 執行型別檢查,稱型別安全下溯造型。上溯造型(Circle→Shape)編譯器自動;下溯造型(Shape→Circle)不保證安全,需明確造型。
回傳布林值,造型前檢查:
if(x instanceof Dog) ((Dog)x).bark();
無其他型別資訊時極重要,否則得 ClassCastException。
//: 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 陳述式顯示設計可能有問題。
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 陣列,無需動程式其他部分。