《Java编程思想》整理的一些学习笔记,有不对的地方,欢迎指出。
1.运行时类别检查:当只有一个指向对象基类的引用时,RTTI机制可以让你找出这个对象的确切类型。主要有两种方式:一种是“传统的”RTTI,它假定我们在编译时和运行时已经知道了所有的类型;另一种是“反射”机制,它允许我们在运行时获得类的信息。向下转型一般用在,假如你碰到了一个特殊的编程问题--如果能够知道某个类型的确切类型,就可以使用最简单的方式去解决它。例如把一具体类型的几何图形变成紫色,以突出显示它,这是就要用到向下转型,就要进行类型转换。
2.类型信息在运行时是通过称为“Class对象”的特殊对象完成的,它包含了与类有关的信息。事实上,Class对象就是用来创建类的所有“普通”对象的。每个类都有一个Class对象,每当编写并编译了一个新类,就会产生一个Class对象(更恰当的说,被保存在一个同名的.class文件中)。在运行时,当我们想生成这个类的对象时,JVM首先检查这个类的Class对象是否已经加载。若未加载,JVM就会查找.class文件,并将其加载。
3.Class.forName("GUM"); 这个方法是Class类(所有Class对象都属于这个类)的一个static成员。Class对象就和其他对象一样,我们可以获取并操作它的引用(这也就是类加载器的工作)。forName()是去的Class对象的引用的一种方法。参数是类名,返回一个Class对象的引用。
4.类字面常量,另一种方法来生成对Class对象的引用,即使用“类字面常量”。格式:GUM.class;这样做不仅最简单,而且更安全,因为它在编译时就会受到检查。并且它无需方法调用,所以更有效。
5.RTTI在Java中还有第三种方式,就是关键字instanceof。它返回一个布尔值,告诉我们对象是不是某个特定类型的实例。可以用提问的方式使用它,就象这样:
if(x instanceof Dog)
((Dog)x).bark();
在将x转型成一个Dog前,上面的if语句会检查对象x是否从属于Dog类。进行向下转型前,如果没有其他信息可以告诉你这个对象是什么类型,那么使用instanceof是非常重要的。
6.动态的instanceof,Class.ifInstance方法提供了一种动态的调用instanceof运算符的途径。
Class[] petTypes={
Pet.class;
Dog.class;
Cat.class;
Pug.class;
}
非动态:for(int i = 0;i<pets.length;i++)
if(o instanceof Pet)
doSomething...;
if(o intstanceof Dog)
doSomething...;
动态:for(int i = 0;i<petTypes.length;i++)
if(petTypes[i].isInstance(o))
doSomething...;
7.三种获得指向Class对象引用的方法:class.forName("类名");、类名.class、对象.getClass();
8.用RTTI类型检查时,有一个限制:这个类型在编译时必须已知,这样才能使用RTTI识别它,即在编译时,编译器必须知道所有要通过RTTI处理的类。
9.RTTI与反射之间真正的区别在于:对RTTI来说,编译器在编译时打开和检查.class文件(换句话说,我们可以用“普通”方式调用对象的所有方法)。而反射机制来说,.class文件在编译时是不可获取的,所以实在运行时打开和检查.class文件。