运行时类型识别:当只有一个指向基类的引用时(多态),RTTI机制可以让你找出这个对象的确切类型。
RTTI
Class对象
类型信息在运行时由“Class对象”完成,它包含了与类有关的信息。Class对象就是用来创建类的所有的“普通”对象的。
类是程序的一部分,每个类都有一个Class对象。
在编写并编译了一个新类时,就会产生一个Class对象(被保存在一个同名的 .Class文件中)。
在运行时,当我们想生成这个类的对象时,JVM首先检查这个类的Class对象是否已经被加载。如果尚未被加载,JVM就会根据类名查找 .Class文件,并将其载入。Java程序并不是一开始执行就被完全加载的。
一旦某个类的Class对象被载入内存,它就被用来创建这个类的所有对象。
Class.forName( String ClassName )方法
Class的静态方法。
该方法返回一个Class对象的引用,如果这个类还未被加载就加载它。如果Class.forName()找不到你要加载的类,它就会抛出ClassNotFoundException。
类字面常量ClassName.class
同样生成对Class对象的引用。
类字面常量在编译时就受到检查,所以更安全;无需方法调用,所以更高效。
类字面常量不仅可以用于普通的类,也可以用于接口、数组以及基本数据类型。
注:基本数据类型的包装器类有一个TYPE字段,它指向对应得基本数据类型的Class对象。
Class.newInstance( )
Class的非静态方法,通过Class对象生成新的实例,将调用缺省的类构造器生成新的对象。
好处:在不知道准确类型的情况下,通过Class对象正确地创建对象。
instanceof
if(x instanceof Dog)
((Dog)x).bark()
返回布尔值,判断对象是不是某个特定类型的实例。
Class.isInstance( Object )
动态的instanceof,Class的非静态方法。
Class.getInterfaces( )
Class的非静态方法,返回Class对象的数组,这些对象代表某个Class对象所包含的接口。
Class.isInterface( )
Class的非静态方法,查看是否是一个接口。
Object.getClass( )
对象获取自身Class对象引用
Class.getSuperclass( )
Class的非静态方法,获取直接基类的Class引用。
等价性instanceof与Class
instanceof和isInstance( )生成的结果完全一样,它们指的是“你是这个类吗,或者你是这个类的派生类吗?”
而如果用==和equals( )来比较实际的Class对象,就没有考虑继承。
RTTI语法
Java通过Class对象实现RTTI机制,即使我们只是做些像类型转换这类的事。
首先,需要获得指向适当的Class对象的引用。办法有:
* Class.forName( )方法。在获取Class引用时无需该类的对象
* Object.getClass( )方法。需要一个类型的对象,返回Class引用,用来表示对象的实际类型。
然后调用上面各种方法。