Think in Java 笔记III 运行期类型鉴定

第11章 运行期类型鉴定

Java提供两种方法:一种是”传统”RTTI,它的限制是:类型必须是在编译期间已知的;另一种是Java1.1特有的”反射”机制,利用它可在运行期独立查找类信息。

RTTI

RTTI技术用它查询继承类句柄的准确类型。包括从interface、abstract或者普通类继承的类型。

每个类都有一个static从句,在类首次载入时执行,可以做一些初始化工作。
class Candy {
static {
System.out.println(”Loading Candy”);
}
}

Class对象

每个类都有一个Class对象。Class对象保存在同名的.class文件中。在运行期,一旦想生成类的对象,JVM首先检查类型的Class对象是否已经载入。若尚未载入,JVM就会查找同名的.class文件,并将其载入。而一旦那个类型的Class对象进入内存,就用它创建那一类型的所有对象。

Class.forName(”Gum”)

为获得Class的一个句柄,一个办法是使用forName(),比如:Class.forName(”Gum”); 它用RTTI确保造型的正确性,并在遇到一个失败的造型后产生一个ClassCastException违例。

类标记Gum.class

类标记更简单,更安全。它会在编译期间得到检查,不会象Class.forName()那样”掷”出违例。而由于它取消了对方法调用的需要,所以执行的效率也会更高。

类标记不仅可以应用于普通类,也可以应用于接口、数组以及基本数据类型。除此以外,针对每种基本数据类型的封装器类,它还存在一个名为TYPE的标准字段,可以为相关的基本数据类型产生Class对象的一个句柄,比如Boolean.TYPE就相当于boolean.class。

造型前检查

1、instanceof 表示对象是不是特定类型的实例。它返回一个布尔值,如:
if(x instanceof Dog)
((Dog)x).bark();

这种需要制定类名Dog的方法叫做静态调用。

2、动态isInstance方法

Java 1.1为Class类添加了isInstance方法。利用它可以动态调用instanceof运算符。如
Object o = pets.elementAt(i); # pets里包括类的Instance
petTypes[j].isInstance(o)) # petTypes里包括类对象

RTTI语法

Java用Class对象实现自己的RTTI功能。

Class提供了几个有趣且较为有用的方法,Class.getInterfaces(); getSuperclass(); newInstance(); toString() = “class c11.petcount2.Pet”; getName(); isInterface();

注意,用newInstance()创建的类必须有一个默认构建器。没有办法用newInstance()创建拥有非默认构建器的对象,所以在Java 1.0中可能存在一些限制。然而,Java 1.1的”反射”API(下一节讨论)却允许我们动态地使用类里的任何构建器。

Class_Instance.getClass();

反射:运行期类信息

假若得到的是不在自己程序空间内的对象的句柄,这时RTTI就无法工作了。比如基于组件的程序设计和远程方法调用”(RMI)。但我们很少需要直接使用反射工具。

新增库:java.lang.reflect提供了针对Field,Method以及Constructor的三个类。这些类型的对象都是JVM在运行期创建的,用于代表未知类里对应的成员。这样便可用构建器创建新对象,用get()和set()方法读取和修改与Field对象关联的字段,以及用invoke()方法调用与Method对象关联的方法。我们可调用方法getFields(),getMethods(),getConstructors(),分别返回用于表示字段、方法以及构建器的对象数组,使匿名对象的类信息在运行期被完整的揭露出来

StreamTokenizer

Technorati :



Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

提示:如果你刚刚提交过评论,但是还没有被显示出来,请点击这里刷新一下: 刷新评论