java之反射

 

什么是反射?通过利用字节码文件通过Class对象获取类中所有数据的方式就是反射。这种技术可以获取到任何定义的信息(包括成员变量,成员方法,构造器等),并且可以操纵类的字段、方法、构造器等部分,这就是的用途。下面说下Class对象。

创建Class对象

1 // 方式一
2 Class<?> clazz1 = Class.forName("cn.tedu.reflection.Student"); //参数是类的全路径
3 
4 // 方式二    
5 Class<?> clazz2 = Student.class;
6 
7 // 方式三     
8 Student s = new Student();
9 Class<?> clazz3 = s.getClass();

常用方法

获得包名、类名

  • clazz.getPackage().getName()//包名
  • clazz.getSimpleName()//类名
  • clazz.getName()//完整类名

成员变量定义信息

  • getFields()//获得所有公开的成员变量,包括继承的变量
  • getDeclaredFields()//获得本类定义的成员变量,包括私有,不包括继承的变量
  • getField(变量名)
  • getDeclaredField(变量名)

构造方法定义信息

  • getConstructor(参数类型列表)//获得公开的构造方法
  • getConstructors()//获得所有公开的构造方法
  • getDeclaredConstructors()//获得所有构造方法,包括私有
  • getDeclaredConstructor(int.class, String.class)

方法定义信息

  • getMethods()//获得所有可见的方法,包括继承的方法
  • getMethod(方法名,参数类型列表)
  • getDeclaredMethods()//获得本类定义的方法,包括私有,不包括继承的方法
  • getDeclaredMethod(方法名, int.class, String.class)

反射新建实例

  • c.newInstance();//执行无参构造
  • c.newInstance(6, "abc");//执行有参构造
  • c.getConstructor(int.class, String.class); //执行含参构造,获取构造方法

反射调用成员变量

  • c.getDeclaredField(变量名); //获取变量
  • c.setAccessible(true); //使私有成员允许访问
  • f.set(实例, 值); //为指定实例的变量赋值,静态变量,第一参数给 null
  • f.get(实例); //访问指定实例的变量的值,静态变量,第一参数给 null

反射调用成员方法

  • Method m = c.getDeclaredMethod(方法名, 参数类型列表);
  • m.setAccessible(true) ;//使私有方法允许被调用
  • m.invoke(实例, 参数数据) ;//让指定的实例来执行该方法

 

封装的反射常用工具类

  1 public class Reflections {
  2 
  3     /**
  4      * 通过forName方法获取Class对象
  5      * 
  6      * @param path 类的全路径
  7      * @return 指定全路径的类的Class对象
  8      */
  9     public static Class<?> forName(String path) {
 10         Class<?> clazz = null;
 11         try {
 12             clazz = Class.forName(path);
 13         } catch (ClassNotFoundException e) {
 14             // TODO Auto-generated catch block
 15             e.printStackTrace();
 16             System.err.println("您输入路径不存在");
 17         }
 18         return clazz;
 19     }
 20 
 21     /**
 22      * 
 23      * @param obj 如果是字符串,就是类的全路径,按照类全路径创建Class对象 如果是对象,按照对象的 getclass()方法创建Class对象
 24      * @return Class对象
 25      */
 26     public static Class<?> getClass(Object obj) {
 27         Class<?> clazz = null;
 28         if (obj instanceof String) {
 29             clazz = forName((String) obj);
 30         } else {
 31             clazz = obj.getClass();
 32         }
 33         return clazz;
 34     }
 35 
 36     /**
 37      * 
 38      * @param para 传入创建Class对象的对象或路径
 39      * @return 传入对象或路径的无参构造函数
 40      */
 41     public static Constructor<?> getConstructor(Object obj) {
 42         Constructor<?> cons = null;
 43         try {
 44             cons = getClass(obj).getConstructor();
 45         } catch (Exception e) {
 46             e.printStackTrace();
 47             System.err.println("您传入的参数不对");
 48         }
 49         return cons;
 50     }
 51 
 52     /**
 53      * 
 54      * @param obj 传入的参数 可以是字符串,也可以是对象
 55      * @return 根据传入的参数返回本类中定义的构造方法,包括私有构造方法
 56      */
 57     public static Constructor<?>[] getDeclaredConstructor(Object obj) {
 58         Constructor<?>[] cons = null;
 59         try {
 60             cons = getClass(obj).getDeclaredConstructors();
 61         } catch (Exception e) {
 62             e.printStackTrace();
 63             System.err.println("您传入的参数不对");
 64         }
 65         return cons;
 66     }
 67 
 68 
 69     public static Method[] getMethods(Object obj, boolean isDeclared) {
 70         Class<?> clazz = getClass(obj);
 71         if (isDeclared) { // 获取本类定义的方法
 72             return clazz.getDeclaredMethods();
 73         } else {
 74             return clazz.getMethods();
 75         }
 76     }
 77 
 78     // 通过重载使用达到函数参数默认值的效果
 79     public static Method[] getMethods(Object obj) {
 80         return getMethods(obj, false);
 81     }
 82 
 83 
 84     /**
 85      * 
 86      * @param obj 传入的类全路径或对象
 87      * @param funcName  被调用的方法名
 88      * @param isDeclared 是否是本类中定义的方法
 89      * @return 返回传入类全路径或对象的实例化Object对象
 90      */
 91     public static Object invokeMethod(Object obj,String funcName, boolean isDeclared) {
 92         Class<?> clazz = getClass(obj);
 93         Method m = null;
 94         Object o = newInstance(obj);
 95             try {
 96                 if(isDeclared) {
 97                     m = clazz.getDeclaredMethod(funcName);
 98                 }else {
 99                     m = clazz.getMethod(funcName);
100                 }
101                 m.setAccessible(true);
102                 m.invoke(o);
103             } catch (Exception e) {
104                 // TODO Auto-generated catch block
105                 e.printStackTrace();
106             } 
107             return o;
108         }
109     
110 
111 
112     /**
113      * 
114      * @param obj 传入参数字符串或对象
115      * @return 返回参数对应的无参构造创建的实例
116      */
117     public static Object newInstance(Object obj) {
118         Object instance = null;
119         try {
120             Constructor<?> cons = getConstructor(obj);
121             instance = cons.newInstance();
122         } catch (Exception e) {
123             e.printStackTrace();
124             System.err.println("实例化失败");
125         } 
126         return instance;
127     }
128     
129 
130     /**
131      * 
132      * @param obj 传入字符串或对象参数
133      * @param isDeclared  是否是本类定义的
134      * @return 返回参数对用的Class对象中的字段/属性
135      */
136     public static Field[] getFields(Object obj, boolean isDeclared) {
137         Class<?> clazz = getClass(obj);
138         if(isDeclared) {
139             return clazz.getDeclaredFields();
140         }else {            
141             return clazz.getFields();
142         }
143     }
144     
145     // 重载实现参数默认值,方便使用
146     public static Field[] getFields(Object obj) {
147         return getFields(obj,false);
148     }
149     
150     
151 
152     
153     /**
154      * 
155      * @param obj 传入的类全路径或对象
156      * @param fieldName 字段名称
157      * @param isDecalred 是否是本类内定义的
158      * @return 返回字段
159      */
160     public static Field getField(Object obj, String fieldName, boolean isDecalred) {
161         Class<?> clazz = getClass(obj);
162         Field field = null;
163         try {
164             if(isDecalred) {
165                 field = clazz.getDeclaredField(fieldName);
166             }else {
167                 field = clazz.getField(fieldName);                                
168             }
169         } catch (Exception e) {
170             e.printStackTrace();
171             System.err.println("字段获取失败");
172         }
173         return field;
174     }
175     
176     // 重载实现参数默认值,方便使用
177     public static Field getField(Object obj, String fieldName) {
178         return getField(obj,fieldName,false);
179     }
180     
181     
182     /**
183      * 
184      * @param obj 传入的字符串或对象
185      * @param fieldName  字段名字
186      * @param fieldValue  字段属性
187      * @param isDeclared  是否是本类中定义的(包括私有属性)
188      */
189     public static Object setField(Object obj, String fieldName,Object fieldValue, boolean isDeclared) {
190         Field f = null;
191         Object value = null;
192         if(isDeclared) {
193             f = getField("cn.tedu.reflection.Person","age",true);
194         }else {
195             f = getField("cn.tedu.reflection.Person","age");
196         }
197         Object instance = newInstance("cn.tedu.reflection.Person");
198         f.setAccessible(true);
199         try {
200             f.set(instance, fieldValue);
201             value = f.get(instance);
202         } catch (IllegalArgumentException e) {
203             e.printStackTrace();
204             System.out.println("设置失败");
205         } catch (IllegalAccessException e) {
206             e.printStackTrace();
207             System.out.println("设置失败");            
208         }
209         return value;
210     }
211     
212     // 重载实现参数默认值,方便使用
213     public static Object setField(Object obj, String fieldName,Object fieldValue) {
214         return setField(obj,fieldName,fieldValue,false);
215     }
216     
217     
218     
219 }

 

 

 

 

posted @ 2020-03-15 22:55  技术狂-CYL  阅读(79)  评论(0)    收藏  举报