按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
非总是这样,所以 RTTI 显得特别方便。
1。 使用类标记
PetCount。java 示例可用Java 1。1 的类标记重写一遍。得到的结果显得更加明确易懂:
//: PetCount2。java
// Using Java 1。1 class literals
338
…………………………………………………………Page 340……………………………………………………………
package c11。petcount2;
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 PetCount2 {
public static void main(String'' args) {
Vector pets = new Vector();
Class'' petTypes = {
// Class literals work in Java 1。1+ only:
Pet。class;
Dog。class;
Pug。class;
Cat。class;
Rodent。class;
Gerbil。class;
Hamster。class;
};
try {
for(int i = 0; i 《 15; i++) {
// Offset by one to eliminate Pet。class:
int rnd = 1 + (int)(
Math。random() * (petTypes。length 1));
pets。addElement(
petTypes'rnd'。newInstance());
}
} catch(InstantiationException e) {}
catch(IllegalAccessException e) {}
Hashtable h = new Hashtable();
for(int i = 0; i 《 petTypes。length; i++)
h。put(petTypes'i'。toString();
new Counter());
for(int i = 0; i 《 pets。size(); i++) {
Object o = pets。elementAt(i);
if(o instanceof Pet)
((Counter)h。get(
〃class c11。petcount2。Pet〃))。i++;
if(o instanceof Dog)
((Counter)h。get(
〃class c11。petcount2。Dog〃))。i++;
if(o instanceof Pug)
((Counter)h。get(
〃class c11。petcount2。Pug〃))。i++;
if(o instanceof Cat)
339
…………………………………………………………Page 341……………………………………………………………
((Counter)h。get(
〃class c11。petcount2。Cat〃))。i++;
if(o instanceof Rodent)
((Counter)h。get(
〃class c11。petcount2。Rodent〃))。i++;
if(o instanceof Gerbil)
((Counter)h。get(
〃class c11。petcount2。Gerbil〃))。i++;
if(o instanceof Hamster)
((Counter)h。get(
〃class c11。petcount2。Hamster〃))。i++;
}
for(int i = 0; i 《 pets。size(); i++)
System。out。println(
pets。elementAt(i)。getClass()。toString());
Enumeration keys = h。keys();
while(keys。hasMoreElements()) {
String nm = (String)keys。nextElement();
Counter cnt = (Counter)h。get(nm);
System。out。println(
nm。substring(nm。lastIndexOf('。') + 1) +
〃 quantity: 〃 + cnt。i);
}
}
} ///:~
在这里,typenames (类型名)数组已被删除,改为从Class 对象里获取类型名称。注意为此而额外做的工
作:例如,类名不是Getbil,而是c11。petcount2。Getbil,其中已包含了包的名字。也要注意系统是能够区
分类和接口的。
也可以看到,petTypes 的创建模块不需要用一个try 块包围起来,因为它会在编译期得到检查,不会象
Class。forName()那样“掷”出任何违例。
Pet 动态创建好以后,可以看到随机数字已得到了限制,位于 1和 petTypes。length 之间,而且不包括零。
那是由于零代表的是Pet。class,而且一个普通的 Pet 对象可能不会有人感兴趣。然而,由于Pet。class 是
petTypes 的一部分,所以所有Pet (宠物)都会算入计数中。
2。 动态的 instanceof
Java 1。1 为Class 类添加了 isInstance方法。利用它可以动态调用 instanceof 运算符。而在Java 1。0
中,只能静态地调用它(就象前面指出的那样)。因此,所有那些烦人的 instanceof语句都可以从
PetCount 例子中删去了。如下所示:
//: PetCount3。java
// Using Java 1。1 isInstance()
package c11。petcount3;
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 {}
340
…………………………………………………………Page 342……………………………………………………………
class Counter { int i; }
public class PetCount3 {
public static void main(String'' args) {
Vector pets = new Vector();
Class'' petTypes = {
Pet。class;
Dog。class;
Pug。class;
Cat。class;
Rodent。class;
Gerbil。class;
Hamster。class;
};
try {
for(int i = 0; i 《 15; i++) {
// Offset by one to eliminate Pet。class:
int rnd = 1 + (int)(
Math。random() * (petTypes。length 1));
pets。addElement(
petTypes'rnd'。newInstance());
}
} catch(InstantiationException e) {}
catch(IllegalAccessException e) {}
Hashtable h = new Hashtable();
for(int i = 0; i 《 petTypes。length; i++)
h。put(petTypes'i'。toString();
new Counter());
for(int i = 0; i 《 pets。size(); i++) {
Object o = pets。elementAt(i);
// Using isInstance to eliminate individual
// instanceof expressions:
for (int j = 0; j 《 petTypes。length; ++j)
if (petTypes'j'。isInstance(o)) {
String key = petTypes'j'。toString();
((Counter)h。get(key))。i++;
}
}
for(int i = 0; i 《 pets。size(); i++)
System。out。println(
pets。elementAt(i)。getClass()。toString());
Enumeration keys = h。keys();
while(keys。hasMoreElements()) {
String nm = (String)keys。nextElement();
Counter cnt = (Counter)h。get(nm);
System。out。println(
nm。substring(nm。lastIndexOf('。') + 1) +
〃 quantity: 〃 + cnt。i);
}
}
341
…………………………………………………………Page 343……………………………………………………………
} ///:~
可以看到,Java 1。1 的isInstance()方法已取消了对 instanceof 表达式的需要。此外,这也意味着一旦要
求添加新类型宠物,只需简单地改变petTypes 数组即可;毋需改动程序剩余的部分(但在使用 instanceof
时却是必需的)。
11。2 RTTI 语法
Java 用Class 对象实现自己的RTTI 功能——即便我们要做的只是象造型那样的一些工作。Class 类也提供了
其他大量方式,以方便我们使用RTTI。
首先必须获得指向适当 Class 对象的的一个句柄。就象前例演示的那样,一个办法是用一个字串以及
Class。forName()方法。这是非常方便的,因为不需要那种类型的一个对象来获取 Class 句柄。然而,对于自
己感兴趣的类型,如果已有了它的一个对象,那么为了取得Class 句柄,可调用属于 Object 根类一部分的一
个方法:getClass()。它的作用是返回一个特定的Class 句柄,用来表示对象的实际类型。Class 提供了几
个有趣且较为有用的方法,从下例即可看出:
//: ToyTest。java
// Testing class Class
interface HasBatteries {}
interface Waterproof {}
interface ShootsThings {}
class Toy {
// ment out the following default
// constructor to see
// NoSuchMethodError from (*1*)
Toy() {}
Toy(int i) {}
}
class FancyToy extends Toy
implements HasBatteries;
Waterproof; ShootsThings {
FancyToy() { super(1); }
}
public class ToyTest {
public static void main(String'' args) {
Class c = null;
try {
c = Class。forName(〃FancyToy〃);
} catch(ClassNotFoundException e) {}
printInfo(c);
Class'' faces = c。getInterfaces();
for(int i = 0; i 《 faces。length; i++)
printInfo(faces'i');
Class cy = c。getSuperclass();
Object o = null;
try {
// Requires default constructor:
o = cy。newInstance(); // (*1*)
} catch(InstantiationExce