RTTI(Run Time Type Information)使得你可以在程序运行的时候获取和使用对象的类型信息。先来一个例子:
1 package re; 2 import java.util.*; 3 public class Reflect{ 4 public static void main(String[] args)throws Exception{ 5 List<shape> sl=Arrays.asList(new circle(),new rectangle(),new square()); 6 for(shape sh:sl){ 7 System.out.println(sh.getClass()); 8 sh.draw(); 9 } 10 Father fs=new Son(); 11 fs.prin(); 12 fs.prin2(); 13 } 14 15 } 16 class Father{ 17 public void prin(){ 18 System.out.println("this is father"); 19 } 20 public void prin2(){ 21 System.out.println("this is father"); 22 } 23 } 24 class Son extends Father{ 25 public void prin(){ 26 System.out.println("this is son"); 27 } 28 } 29 abstract class shape{ 30 void draw(){ 31 System.out.println(" "+this+".draw()"); 32 } 33 abstract public String toString(); 34 } 35 class circle extends shape{ 36 public String toString(){ 37 return "circle"; 38 } 39 } 40 class rectangle extends shape{ 41 public String toString(){ 42 return "rectangle"; 43 } 44 } 45 class square extends shape{ 46 public String toString(){ 47 return "square"; 48 } 49 }
这里我们创建的对象的变量类型是shape类型(也就是父类型,也即 father fs=new son(),其中son类继承/实现father),但是在执行draw()方法时,可以获取对象的实际类型的信息,这就是RTTI提供的机制功能,面向对象的多态特性与RTTI机制是分不开的。java的所有类的基类Object中有一个方法: getClass(),java API文档对其作用的描述是“返回此Object的运行时类”,也就是返回创建引用所指向的对象的类,例 father fs=new son(),fs.getClass()返回的是son类,该方法返回类型是Class<T>类型,java API对Class对象的描述是“Class
类的实例表示正在运行的 Java 应用程序中的类和接口”。从而我们可以得知:Class对象关系到我们想要了解的正在运行的对象的类信息。这里对Class对象做一下总结:
Class对象包含了与类有关的信息,《Thinking in Java》中陈述说“Class对象就是用来创建类的所有常规对象的”,也就是我们创建一个对象时,是用这个类的Class对象完成创建工作的。每一个类都有一个Class对象,当我们创建并编译好了一个新类,就会产生一个Class对象,并且该对象被保存在一个同名的.class文件中!当要创建一个类的对象时,类加载器首先会检查这个类的Class对象是否已加载,若没有,类加载器就会根据类名查找.class文件,并将其加载到内存中,然后就用.class中的Class对象去创建这个类的所有对象。
那么,我们可以通过获取一个正在运行的类对象的Class对象,进而通过该Class对象获取对象运行时使用的类型信息了。例如,我们可以获得这个创建这个对象的类中所定义的所有方法,代码如下:
1 package re; 2 import java.util.*; 3 import java.lang.reflect.*; 4 public class Reflect{ 5 public static void main(String[] args)throws Exception{ 6 List<shape> sl=Arrays.asList(new circle(),new rectangle(),new square()); 7 for(shape sh:sl){ 8 Class T=sh.getClass(); 9 Method[] me=T.getDeclaredMethods(); 10 System.out.println(T); 11 for(Method m1:me ) 12 System.out.println(" "+m1); 13 System.out.println("-------------------"); 14 } 15 } 16 17 } 18 abstract class shape{ 19 void draw(){ 20 System.out.println(" "+this+".draw()"); 21 } 22 abstract public String toString(); 23 } 24 class circle extends shape{ 25 public String toString(){ 26 return "circle"; 27 } 28 } 29 class rectangle extends shape{ 30 public String toString(){ 31 return "rectangle"; 32 } 33 private void printRectangle(){ 34 35 } 36 } 37 class square extends shape{ 38 public String toString(){ 39 return "square"; 40 } 41 }
通过运行结果可知,rectangle还有一个私有的printRectangle()方法,当然,我们还可以获取类中定义的成员变量等信息,对于Class对象的知识点先总结到这里。