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 }

浙公网安备 33010602011771号