《Thinking in Java》_类型信息与反射机制
首先介绍一个本文后面会频繁提到的概念:RTTI(Runtime Type Information,或者,Run-Time Type Identification),运行时类型信息。简单来说,就是指程序能够在运行时发现和使用类型信息。
? ? ? ?RTTI能做什么??它解放了程序在编期间执行的面向类型的操作,不管是程序的安全性还是可扩展性和可维护性,都得到了大大的加强。
? ? ? 我们一般使用二种方式来实现运行时识别对象和类的信息:“传统的”RTTI和“反射”机制。
一、一个大家都熟悉的例子
传统的RTTI假定我们在编译时已经知道了所有的信息。
下面我们来看一看一个很熟悉的例子:
?
CocaCola类继承自Cola类并实现了Drinkable、Sellable接口。在mian方法中,我们用forName()方法创建了一个
Class对象的引用。需要注意的是,forName()方法传入的参数必须是全限定名(就是包含包名)
?
在printinfo()方法中,分别使用getSimpleName()和getCanonicalName()来打印出不含包名的类名和全限定的类名。isInterface()很明显,是得到这个class对象是否表示一个接口。虽然,我们这里只是演示了class对象的3种方法,但实际上,通过class对象,我们发现我们能够了解到类型的几乎所有的信息(之所以是“几乎”是因为我们有时候并不需要客户了解我们提供的类的某些信息,而选择性的屏蔽。大家可以试一试用class对象查询某些类的private属性!)
?
例子有出现了三种不同的获得class对象的方法:
Class.forName():最简单的,也是最快捷的方式,因为我们并不需要为了获得class对象而持有该类的对象实例。
obj.getClass():当我们已经拥有了一个感兴趣的类型的对象时,这个方法很好用。
Obj.class : ?类字面常量,这种方式很安全,因为它在编译时就会得到检查(因此不需要放到try语句块中),而且高效。
我们可以根据我们的程序的条件和需要,选择上面三种方式中的任何一种来实现RTTI。
?
?
四、泛化的Class引用
通过上面的例子我们可以很容易的知道,class引用表示的是它所指向的对象的确切类型,并且,通过class对象我们
能获取特定类的几乎所有信息。这很容易理解。
?
但是,Java的设计者并不止步于此。通过泛型,我们可以让class引用所指向的类型更加具体。
?
package cn.OOP.Typeinfo;
cn.OOP.Typeinfo.ACommonClasssuccessed load the Class:cn.OOP.Typeinfo.ACommonClass?在这个例子中,我们看到了一个和以前传统的编程截然不同的东西:在程序运行时,我们还能云淡风轻的写着程序必须的类,而且,这个类还能用于这个已经开始的程序!!!!神奇吧。
?
当然,这只是一个最简单的RTTI反射应用,通常的Java动态编程会更复杂,也更神奇!!
?
Class类与java.lang.reflect类库一起对反射机制提供了支持。当通过反射与一个未知类型的对象打交道时,JVM只是简单的检查这个对象,看他属于哪个特定的类(就像传统的RTTI一样)。当我们用反射机制做某些事情时,我们还是必须知道特定的类(也就是必须得到.class文件),要么在本地,要么从网络获取。所不同的是,由于设计体系的特殊,我们逃避了在编译期间的检查,知道运行时猜打开和检查.class文件。
?
未完待续!!!!
等会更新
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?