Java反射的理解

反射的作用:
 
1.运行时检查类的结构
2.运行时更改类的字段值
3.调用类的方法
 
准备知识:
 
Class类:虚拟机为每一个对象保存的一份对象所属类的清单:
static Class forName(String className) 获取字符串(接口或者类的全类名)对应的类的Class对象。
Object newInstance() 返回Class对应的类的一个对象
 
解析: 
1.运行时检查类的结构
    java.lang.reflection 中有三个类:
    1.Field 对应类的字段
        getName() 返回Field对应的名称
        getType() 返回Field所在的Class类型
    2.Method 对应类的方法
        getName() 返回Method 对应的名称
        Class<?>[] getParameterTypes() 按方法声明的顺序返回参数类型数组
        int getModifiers() 返回一个整数值,用不同的位开关表示static,public这样的修饰情况。
    3.Constructor 对应构造器
        getName() 返回Constructor 对应的名称
        Class<?>[] getParameterTypes() 按方法声明的顺序返回参数类型数组
        int getModifiers() 返回一个整数值,用不同的位开关表示static,public这样的修饰情况。
 
在Method和Constructor中可以使用Modifier类的isPrivate,isStatic 来判断getModifiers()的返回值,给出是否含有对应的修饰符。
Class对象的getDeclaredConstructors,getDeclaredMethods,getDeclaredFields分别用于获取对象的构造器,方法,字段,以数组的形式返回。
 
下面为反射基本用法:检测一个类的结构:
 
 1 import java.lang.reflect.Constructor;
 2 import java.lang.reflect.Field;
 3 import java.lang.reflect.Method;
 4 import java.lang.reflect.Modifier;
 5 
 6 //反射基本测试
 7 public class ReflectionTest {
 8     public static void main(String[] args) {
 9         String name = "java.util.Date";
10         try {
11             Class cl = Class.forName(name);
12             Class supercl = cl.getSuperclass();
13             String modifiers = Modifier.toString(cl.getModifiers());
14             if (modifiers.length() > 0) System.out.print(modifiers + " ");
15             System.out.print("class " + name);
16             if (supercl != null && supercl != Object.class) System.out.print(" extends "
17                     + supercl.getName());
18 
19             System.out.print("\n{\n");
20             printConstructors(cl);
21             System.out.println();
22             printMethods(cl);
23             System.out.println();
24             printFields(cl);
25             System.out.println("}");
26         } catch (ClassNotFoundException e) {
27             e.printStackTrace();
28         }
29         System.exit(0);
30     }
31 
32 
33     public static void printConstructors(Class cl) {
34         Constructor[] constructors = cl.getDeclaredConstructors();
35 
36         for (Constructor c : constructors) {
37             String name = c.getName();
38             System.out.print("   ");
39             String modifiers = Modifier.toString(c.getModifiers());
40             if (modifiers.length() > 0) System.out.print(modifiers + " ");
41             System.out.print(name + "(");
42 
43             // print parameter types
44             Class[] paramTypes = c.getParameterTypes();
45             for (int j = 0; j < paramTypes.length; j++) {
46                 if (j > 0) System.out.print(", ");
47                 System.out.print(paramTypes[j].getName());
48             }
49             System.out.println(");");
50         }
51     }
52 
53 
54     public static void printMethods(Class cl) {
55         Method[] methods = cl.getDeclaredMethods();
56 
57         for (Method m : methods) {
58 
59             Class retType = m.getReturnType();
60             String name = m.getName();
61 
62             System.out.print("   ");
63             // print modifiers, return type and method name
64             String modifiers = Modifier.toString(m.getModifiers());
65             if (modifiers.length() > 0) System.out.print(modifiers + " ");
66             System.out.print(retType.getName() + " " + name + "(");
67 
68             // print parameter types
69             Class[] paramTypes = m.getParameterTypes();
70             for (int j = 0; j < paramTypes.length; j++) {
71                 if (j > 0) System.out.print(", ");
72                 System.out.print(paramTypes[j].getName());
73             }
74             System.out.println(");");
75         }
76     }
77 
78 
79     public static void printFields(Class cl) {
80         Field[] fields = cl.getDeclaredFields();
81 
82         for (Field f : fields) {
83             Class type = f.getType();
84             String name = f.getName();
85             System.out.print("   ");
86             String modifiers = Modifier.toString(f.getModifiers());
87             if (modifiers.length() > 0) System.out.print(modifiers + " ");
88             System.out.println(type.getName() + " " + name + ";");
89         }
90     }
91 }

 

 

2.更改类的字段值:
    Field对象有以下对应的一系列方法:
    public Object get(Object obj) 获取目标对象上字段的值
    public void set(Object obj, Object value)设置目标对象上字段的值
    有相应具体类型的get和set方法。
 
3.调用类的方法(类似于方法指针):
    Method对象方法:
     public Object invoke(Object obj, Object... args)
    obj是调用的目标对象,ars是方法参数
 
以下为示例代码:
 1 import java.lang.reflect.Field;
 2 import java.lang.reflect.InvocationTargetException;
 3 import java.lang.reflect.Method;
 4 
 5 /**
 6  * Created by karlx on 2015/5/29.
 7  */
 8 public class ReflectionTest2 {
 9     public static void main(String[] args) {
10         Person person = new Person();
11         person.name = "karl";
12         //获取,设置 运行中对象的字段值
13         Class clazz = person.getClass();
14         try {
15             Field field = clazz.getField("name");
16             field.setAccessible(true);//避开java的访问检查
17             System.out.println(field.get(person));
18 
19             field.set(person, "xiaoming");
20             System.out.println(field.get(person));
21 
22         } catch (NoSuchFieldException | IllegalAccessException e) {
23             e.printStackTrace();
24         }
25         //运行中调用对象的方法
26         try {
27             Method method = clazz.getMethod("getName");
28             method.setAccessible(true);//避开java的访问检查
29             System.out.println(method.invoke(person));
30         } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
31             e.printStackTrace();
32         }
33     }
34 
35     static class Person {
36         public String name;
37 
38         public String getName() {
39             return name + "hello";
40         }
41 
42         public void setName(String name) {
43             this.name = name;
44         }
45     }
46 }

 

posted @ 2015-06-02 22:41  wu.xiaowei  阅读(488)  评论(0编辑  收藏  举报