Java反射机制

一、什么是反射机制

  JAVA反射机制是在运行状态中,对于任意一个,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

  Java反射机制主要提供了以下功能:在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。

  关于动态代理大家可以参考 http://www.cnblogs.com/yfyzy/p/4401833.html

 

二、反射机制和传统的RTTI区别

  RTTI和反射之间的真正区别在于,对RTTI来说,编译器在编译时打开和检查.class文件。(换句话,我们可以用“普通”方式调用对象的所有方法。)而对于反射机制来说,.class文件在编译时是不可以获取的,所以在运行时打开和检查.class文件。

 

三、反射机制实现

  反射机制基于Java的类型信息实现,关于Java类型信息可以参考 http://www.cnblogs.com/yfyzy/p/4398448.html 

  Java的反射机制的实现要借助于4个类:class,Constructor,Field,Method。

  1).Class ——类对象

  2).Constructor——类的构造器对象

  3).Field——类的属性对象

  4).Method——类的方法对象。

 

四、Java 反射机制主要提供了以下功能

  1).在运行时判断任意一个对象所属的类。

  2).在运行时构造任意一个类的对象。

  3).在运行时判断任意一个类所具有的成员变量和方法。

  4).在运行时调用任意一个对象的方法和访问任意一个对象的属性。

 

五 、反射机制中常用的一些方法

  1、得到构造器的方法 

    1)Constructor getConstructor(Class[] params) -- 获得使用特殊的参数类型的公共构造函数, 

    2)Constructor[] getConstructors() -- 获得类的所有公共构造函数 

    3)Constructor getDeclaredConstructor(Class[] params) -- 获得使用特定参数类型的构造函数(与接入级别    无关) 

    4)Constructor[] getDeclaredConstructors() -- 获得类的所有构造函数(与接入级别无关) 

  2、获得字段信息的方法 

    1)Field getField(String name) -- 获得命名的公共字段 

    2)Field[] getFields() -- 获得类的所有公共字段 

    3)Field getDeclaredField(String name) -- 获得类所有声明的命名的字段 

    4)Field[] getDeclaredFields() -- 获得类声明的所有字段 

  3、获得方法信息的方法 

    1)Method getMethod(String name, Class[] params) -- 使用特定的参数类型,获得命名的公共方法 

    2)Method[] getMethods() -- 获得类的所有公共方法 

    3)Method getDeclaredMethod(String name, Class[] params) -- 使用特写的参数类型,获得类声明的命名    的方法 

    4)Method[] getDeclaredMethods() -- 获得类声明的所有方法 

 

六、总结+实践

  在程序开发中使用反射并结合属性文件,可以达到程序代码与配置文件相分离的目的如果我们想要得到对象的信息,一般需要“引入需要的‘包.类’的名称——通过new实例化——取得实例化对象”这样的过程。使用反射就可以变成“实例化对象——getClass()方法——得到完整的‘包.类’名称”这样的过程。正常方法是通过一个类创建对象,反射方法就是通过一个对象找到一个类的信息。

   下面是一个通过反射机制调用类的例子。该例子是小弟在一个前辈的基础上的一点点小改动,感觉这位前辈写的挺好的。这个是那位前辈的博客URL: http://blog.csdn.net/nieweilin/article/details/5908165

  1 import java.lang.reflect.Array;     
  2 import java.lang.reflect.Constructor;     
  3 import java.lang.reflect.Field;     
  4 import java.lang.reflect.Method;     
  5     
  6     
  7 /**   
  8  * Java Reflection Cookbook   
  9  *   
 10  * @author Michael Lee   
 11  * @since 2015-4-09   
 12  * @version 0.2a   
 13  */    
 14     
 15 public class Reflection {     
 16     /**   
 17      * 得到某个对象的属性   
 18      *   
 19      * @param owner, fieldName   
 20      * @return 该属性对象   
 21      * @throws Exception   
 22      *   
 23      */   
 24     
 25     public Object getProperty(Object owner, String fieldName) throws Exception {     
 26         Class ownerClass = owner.getClass();     
 27     
 28         //该写法只能获取该对象的所有公有的属性
 29         //Field field = ownerClass.getField(fieldName); 
 30         
 31         //该写法可以获取对对象的所有属性
 32         Field field = ownerClass.getDeclaredField(fieldName);
 33         
 34         //设置访问权限控制,当为true时,私有属性也可以访问
 35         field.setAccessible(true);    
 36   
 37         return field.get(owner);     
 38     }  
 39     
 40     
 41     /**   
 42      * 得到某类的静态公共属性   
 43      *   
 44      * @param className   类名   
 45      * @param fieldName   属性名   
 46      * @return 该属性对象   
 47      * @throws Exception   
 48      */    
 49     public Object getStaticProperty(String className, String fieldName)     
 50             throws Exception {     
 51         Class ownerClass = Class.forName(className);     
 52     
 53         //该写法只能获取该对象的所有公有的属性
 54         //Field field = ownerClass.getField(fieldName); 
 55         
 56         //该写法可以获取对对象的所有属性
 57         Field field = ownerClass.getDeclaredField(fieldName);
 58         
 59         //设置访问权限控制,当为true时,私有属性也可以访问
 60         field.setAccessible(true);    
 61   
 62         return field.get(ownerClass);    
 63     }     
 64     
 65     
 66     /**   
 67      * 执行某对象方法   
 68      *   
 69      * @param owner   
 70      *            对象   
 71      * @param methodName   
 72      *            方法名   
 73      * @param args   
 74      *            参数   
 75      * @return 方法返回值   
 76      * @throws Exception   
 77      */    
 78     public Object invokeMethod(Object owner, String methodName, Object[] args)     
 79             throws Exception {     
 80     
 81         Class ownerClass = owner.getClass();     
 82     
 83         Class[] argsClass = new Class[args.length];     
 84     
 85         for (int i = 0, j = args.length; i < j; i++) {     
 86             argsClass[i] = args[i].getClass();     
 87         }     
 88     
 89         //该写法只能调用该对象的公有方法
 90        // Method method = ownerClass.getMethod(methodName, argsClass); 
 91         
 92         //该写法可以调用该对象的所有方法
 93         Method method = ownerClass.getDeclaredMethod(methodName, argsClass);
 94     
 95         //设置访问权限控制,当为true时,私有方法也可以访问
 96         method.setAccessible(true);
 97         
 98         return method.invoke(owner, args);     
 99     }     
100     
101     
102       /**   
103      * 执行某类的静态方法   
104      *   
105      * @param className   
106      *            类名   
107      * @param methodName   
108      *            方法名   
109      * @param args   
110      *            参数数组   
111      * @return 执行方法返回的结果   
112      * @throws Exception   
113      */    
114     public Object invokeStaticMethod(String className, String methodName,     
115             Object[] args) throws Exception {     
116         Class ownerClass = Class.forName(className);     
117     
118         Class[] argsClass = new Class[args.length];     
119     
120         for (int i = 0, j = args.length; i < j; i++) {     
121             argsClass[i] = args[i].getClass();     
122         }     
123     
124          //该写法只能调用该类的静态公有方法
125         // Method method = ownerClass.getMethod(methodName, argsClass);     
126     
127         //该写法可以调用该类的所有静态方法
128         Method method = ownerClass.getDeclaredMethod(methodName, argsClass);
129         
130         //设置访问权限控制,当为true时,私有方法也可以访问
131         method.setAccessible(true);
132         
133         return method.invoke(null, args);     
134     }     
135     
136     
137     
138     /**   
139      * 新建实例   
140      *   
141      * @param className   
142      *            类名   
143      * @param args   
144      *            构造函数的参数   
145      * @return 新建的实例   
146      * @throws Exception   
147      */    
148     public Object newInstance(String className, Object[] args) throws Exception {     
149         Class newoneClass = Class.forName(className);     
150     
151         Class[] argsClass = new Class[args.length];     
152     
153         for (int i = 0, j = args.length; i < j; i++) {     
154             argsClass[i] = args[i].getClass();     
155         }     
156     
157        //该写法只能获取该类的公有构造函数
158         //Constructor cons = newoneClass.getConstructor(argsClass);     
159     
160         //该写法可以获取该类的所有构造函数
161         Constructor cons = newoneClass.getDeclaredConstructor(argsClass); 
162         
163         //设置访问权限控制,当为true时,私有方法也可以访问
164         cons.setAccessible(true);
165         
166         return cons.newInstance(args);     
167     
168     }     
169     
170     
171          
172     /**   
173      * 是不是某个类的实例   
174      * @param obj 实例   
175      * @param cls 类   
176      * @return 如果 obj 是此类的实例,则返回 true   
177      */    
178     public boolean isInstance(Object obj, Class cls) {     
179         return cls.isInstance(obj);     
180     }     
181          
182     /**   
183      * 得到数组中的某个元素   
184      * @param array 数组   
185      * @param index 索引   
186      * @return 返回指定数组对象中索引组件的值   
187      */    
188     public Object getByArray(Object array, int index) {     
189         return Array.get(array,index);     
190     }     
191 }    

 

posted @ 2015-04-08 21:45  风走了,雨停了  阅读(203)  评论(0编辑  收藏  举报