Java RTTI 和 反射机制

运行时,识别对象和类的信息有两种方法:
     1、RTTI
     2、“反射”机制
 
RTTI 即 Run Time Type Identification 运行时类型识别
在java中,RTTI表现在:
  1、Class对象是RTTI的核心,每个类都有一个Class对象
  2、instanceof 关键字,用于检查对象是不是某个特定类型的实例
  3、强制类型转换
 
RTTI示例:
 1 public class RTTITest {
 2 
 3     public static void main(String[] args) {
 4         Number n = 123L;
 5 
 6         //c1 c2 c3都是java.lang.Class类的对象
 7         Class<? extends Number> c1 = n.getClass();
8 Class<Number> c2=Number. class; 9 Class<Long> c3=Long. class; 10 11 System. out.println(c1.getName()); 12 System. out.println(c2.getName()); 13 System. out.println(c3.getName()); 14 15 //== 和 equals()是等价的 16 System. out.println((c1==c2)+" " +(c1.equals(c2))); 17 System. out.println(c1.equals(c3)); 18 19 //instanceof 关键字和Class.isInstance等价的 20 //指“你是这个类吗?或者 你是这个类的派生类吗?” 21 System. out.println(n instanceof Number); 22 System. out.println(Number.class.isInstance(n)); 23 System. out.println(n instanceof Long); 24 System. out.println(Long.class.isInstance(n)); 25 } 26 }
输出:
java.lang.Long     ---- n.getClass().返回对象n运行时的Class对象,所以是Long.class,而不是Number.class
java.lang.Number
java.lang.Long

false false
true

true
true
true
true

 

Java语言的反射机制
使java具有动态语言的特性:动态获取类的信息、动态调用类的方法
 
Java反射机制提供一下功能:
  1、运行时判断任意一个对象所属的类
  2、运行时构造任意一个类的对象
  3、运行时判读任意一个类所具有的成员变量和方法(通过反射甚至可以调用private方法)
  4、运行时调用任意一个对象的方法
 
Java反射机制相关的API简介(位于java.lang.reflect)
  Class类:代表一个类
  Field类:代表类的成员变量
  Method类:代表类的方法
  Constructor类:代表类的构造方法
 
 1 import java.lang.reflect.Field;
 2 import java.lang.reflect.Method;
 3 import java.lang.reflect.Modifier;
 4 
 5 
 6 class Person{
 7     private final String name;
 8     private int age = 20;
 9     private String sex;
10 
11     public Person(String name) {
12         this.name = name;
13     }
14     public void sayHello(String name, int age) {
15         System.out.println(name + "  " + age);
16     }
17 
18     public int getAge() {
19         return age;
20     }
21     public void setAge(int age) {
22         this.age = age;
23     }
24     public String getSex() {
25         return sex;
26     }
27     public void setSex(String sex) {
28         this.sex = sex;
29     }
30     public String getName() {
31         return name;
32     }
33 }
34 
35 public class WatchClassInfo {
36 
37     public static void main(String[] args) throws Exception {
38         Person person = new Person("Shao");
39         person.setSex("man");
40         Class<?> c = person.getClass();//获得运行时对象的类对象
41         Class<?> superClass=person.getClass().getSuperclass();//获得运行时对象的基类类对象
42 
43         System.out.println("class loader : "+c.getClassLoader());
44         System.out.println("class name : "+c.getName());
45         System.out.println("super class name "+superClass.getName());
46 
47 
48         System.out.println("-----------查看类中声明的数据成员,及其值-----------");
49         Field[] fields=c.getDeclaredFields();//获得类的数据成员信息
50         for (int i = 0; i < fields.length; i++) {
51             Field field=fields[i];
52             System.out.print(field.getType().getSimpleName()+" "+field.getName());
53 
54             String fieldName=field.getName();
55             String upper=fieldName.substring(0, 1).toUpperCase();
56             String getName="get"+upper+fieldName.substring(1);
57             Method getMethod=c.getMethod(getName, new Class[]{});
58 
59             Object fieldValue=getMethod.invoke(person,new Object[]{});//在person对象上调用getter方法
60             System.out.println(" = "+fieldValue);
61         }
62 
63 
64         System.out.println("-----------查看类中声明的方法-------------------");
65         Method method[] = c.getDeclaredMethods();//获得类的方法信息
66         for (int i = 0; i < method.length; ++i) {
67             Class<?> returnType = method[i].getReturnType();
68             Class<?> para[] = method[i].getParameterTypes();
69             int temp = method[i].getModifiers();
70             System.out.print(Modifier.toString(temp) + " "+returnType.getName() + "  "+method[i].getName() + " "+"(");
71 
72             for (int j = 0; j < para.length; ++j) {
73                 System.out.print(para[j].getName() + " " + "arg" + j);
74                 if (j < para.length - 1) {
75                     System.out.print(",");
76                 }
77             }
78             System.out.println(")");
79         }
80     }
81 
82 }

输出:
class loader : sun.misc.Launcher$AppClassLoader@addbf1
class name : edu.shao.typeinfo.reflect.Person
super class name java.lang.Object
-----------查看类中声明的数据成员,及其值-----------
String name = Shao
int age = 20
String sex = man
-----------查看类中声明的方法-------------------
public void  setSex (java.lang.String arg0)
public void  sayHello (java.lang.String arg0,int arg1)
public int  getAge ()
public void  setAge (int arg0)
public java.lang.String  getSex ()
public java.lang.String  getName ()

 

RTTI和反射之间真正的区别在于:
  1、对于RTTI来说,编辑器在编译时打开或检查.class文件。换句话说,我们可以用“普通”方法调用对象的所有方法。
  2、对于反射机制来说,.class文件在编译时是不可获取的,所以是在运行时打开和检查.class文件。
posted @ 2013-02-22 10:51  windlaughing  阅读(414)  评论(0编辑  收藏  举报