反射工具类源码


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

  Java Reflection

    Reflection(反射)是被视为动态语言的关键,反射机制允许程序在执行期借助于Reflection API取得任何类的内部信息,并能直接操作任意对象的内部属性及方法

  Java反射机制提供的功能

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

    在运行时构造任意一个类的对象

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

    在运行时调用任意一个对象的成员变量和方法

    生成动态代理

  反射相关的主要API:

    java.lang.Class:代表一个类

    java.lang.reflect.Method:代表类的方法

    java.lang.reflect.Field:代表类的成员变量

    java.lang.reflect.Constructor:代表类的构造方法

  。。。。。。

 

 

 1 import java.lang.reflect.Field;  2 import java.lang.reflect.InvocationTargetException;  3 import java.lang.reflect.Method;  4 import java.lang.reflect.Modifier;  5 import java.lang.reflect.ParameterizedType;  6 import java.lang.reflect.Type;  7 
 8 import org.apache.commons.lang3.StringUtils;  9 import org.apache.commons.lang3.Validate;  10 import org.slf4j.Logger;  11 import org.slf4j.LoggerFactory;  12 import org.springframework.util.Assert;  13 
 14 /**
 15  * 反射工具类.  16  * 提供调用getter/setter方法, 访问私有变量, 调用私有方法, 获取泛型类型Class, 被AOP过的真实类等工具函数.  17  */
 18 //压制警告,即去除警告 
 19 @SuppressWarnings("rawtypes")  20 public class Reflections {  21     
 22     private static final String SETTER_PREFIX = "set";  23 
 24     private static final String GETTER_PREFIX = "get";  25 
 26     private static final String CGLIB_CLASS_SEPARATOR = "$$";  27     
 28     private static Logger logger = LoggerFactory.getLogger(Reflections.class);  29 
 30     /**
 31  * 调用Getter方法.  32  * 支持多级,如:对象名.对象名.方法  33      */
 34     public static Object invokeGetter(Object obj, String propertyName) {  35         Object object = obj;  36         for (String name : StringUtils.split(propertyName, ".")){  37             String getterMethodName = GETTER_PREFIX + StringUtils.capitalize(name);  38             object = invokeMethod(object, getterMethodName, new Class[] {}, new Object[] {});  39  }  40         return object;  41  }  42 
 43     /**
 44  * 调用Setter方法, 仅匹配方法名。  45  * 支持多级,如:对象名.对象名.方法  46      */
 47     public static void invokeSetter(Object obj, String propertyName, Object value) {  48         Object object = obj;  49         String[] names = StringUtils.split(propertyName, ".");  50         for (int i=0; i<names.length; i++){  51             if(i<names.length-1){  52                 String getterMethodName = GETTER_PREFIX + StringUtils.capitalize(names[i]);  53                 object = invokeMethod(object, getterMethodName, new Class[] {}, new Object[] {});  54             }else{  55                 String setterMethodName = SETTER_PREFIX + StringUtils.capitalize(names[i]);  56                 invokeMethodByName(object, setterMethodName, new Object[] { value });  57  }  58  }  59  }  60 
 61     /**
 62  * 直接读取对象属性值, 无视private/protected修饰符, 不经过getter函数.  63      */
 64     public static Object getFieldValue(final Object obj, final String fieldName) {  65         Field field = getAccessibleField(obj, fieldName);  66 
 67         if (field == null) {  68             throw new IllegalArgumentException("Could not find field [" + fieldName + "] on target [" + obj + "]");  69  }  70 
 71         Object result = null;  72         try {  73             result = field.get(obj);  74         } catch (IllegalAccessException e) {  75             logger.error("不可能抛出的异常{}", e.getMessage());  76  }  77         return result;  78  }  79 
 80     /**
 81  * 直接设置对象属性值, 无视private/protected修饰符, 不经过setter函数.  82      */
 83     public static void setFieldValue(final Object obj, final String fieldName, final Object value) {  84         Field field = getAccessibleField(obj, fieldName);  85 
 86         if (field == null) {  87             throw new IllegalArgumentException("Could not find field [" + fieldName + "] on target [" + obj + "]");  88  }  89 
 90         try {  91  field.set(obj, value);  92         } catch (IllegalAccessException e) {  93             logger.error("不可能抛出的异常:{}", e.getMessage());  94  }  95  }  96 
 97     /**
 98  * 直接调用对象方法, 无视private/protected修饰符.  99  * 用于一次性调用的情况,否则应使用getAccessibleMethod()函数获得Method后反复调用. 100  * 同时匹配方法名+参数类型, 101      */
102     public static Object invokeMethod(final Object obj, final String methodName, final Class<?>[] parameterTypes, 103             final Object[] args) { 104         Method method = getAccessibleMethod(obj, methodName, parameterTypes); 105         if (method == null) { 106             throw new IllegalArgumentException("Could not find method [" + methodName + "] on target [" + obj + "]"); 107  } 108 
109         try { 110             return method.invoke(obj, args); 111         } catch (Exception e) { 112             throw convertReflectionExceptionToUnchecked(e); 113  } 114  } 115 
116     /**
117  * 直接调用对象方法, 无视private/protected修饰符, 118  * 用于一次性调用的情况,否则应使用getAccessibleMethodByName()函数获得Method后反复调用. 119  * 只匹配函数名,如果有多个同名函数调用第一个。 120      */
121     public static Object invokeMethodByName(final Object obj, final String methodName, final Object[] args) { 122         Method method = getAccessibleMethodByName(obj, methodName); 123         if (method == null) { 124             throw new IllegalArgumentException("Could not find method [" + methodName + "] on target [" + obj + "]"); 125  } 126 
127         try { 128             return method.invoke(obj, args); 129         } catch (Exception e) { 130             throw convertReflectionExceptionToUnchecked(e); 131  } 132  } 133 
134     /**
135  * 循环向上转型, 获取对象的DeclaredField, 并强制设置为可访问. 136  * 137  * 如向上转型到Object仍无法找到, 返回null. 138      */
139     public static Field getAccessibleField(final Object obj, final String fieldName) { 140         Validate.notNull(obj, "object can't be null"); 141         Validate.notBlank(fieldName, "fieldName can't be blank"); 142         for (Class<?> superClass = obj.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()) { 143             try { 144                 Field field = superClass.getDeclaredField(fieldName); 145  makeAccessible(field); 146                 return field; 147             } catch (NoSuchFieldException e) {//NOSONAR 148                 // Field不在当前类定义,继续向上转型
149                 continue;// new add
150  } 151  } 152         return null; 153  } 154 
155     /**
156  * 循环向上转型, 获取对象的DeclaredMethod,并强制设置为可访问. 157  * 如向上转型到Object仍无法找到, 返回null. 158  * 匹配函数名+参数类型。 159  * 160  * 用于方法需要被多次调用的情况. 先使用本函数先取得Method,然后调用Method.invoke(Object obj, Object... args) 161      */
162     public static Method getAccessibleMethod(final Object obj, final String methodName, 163             final Class<?>... parameterTypes) { 164         Validate.notNull(obj, "object can't be null"); 165         Validate.notBlank(methodName, "methodName can't be blank"); 166 
167         for (Class<?> searchType = obj.getClass(); searchType != Object.class; searchType = searchType.getSuperclass()) { 168             try { 169                 Method method = searchType.getDeclaredMethod(methodName, parameterTypes); 170  makeAccessible(method); 171                 return method; 172             } catch (NoSuchMethodException e) { 173                 // Method不在当前类定义,继续向上转型
174                 continue;// new add
175  } 176  } 177         return null; 178  } 179 
180     /**
181  * 循环向上转型, 获取对象的DeclaredMethod,并强制设置为可访问. 182  * 如向上转型到Object仍无法找到, 返回null. 183  * 只匹配函数名。 184  * 185  * 用于方法需要被多次调用的情况. 先使用本函数先取得Method,然后调用Method.invoke(Object obj, Object... args) 186      */
187     public static Method getAccessibleMethodByName(final Object obj, final String methodName) { 188         Validate.notNull(obj, "object can't be null"); 189         Validate.notBlank(methodName, "methodName can't be blank"); 190 
191         for (Class<?> searchType = obj.getClass(); searchType != Object.class; searchType = searchType.getSuperclass()) { 192             Method[] methods = searchType.getDeclaredMethods(); 193             for (Method method : methods) { 194                 if (method.getName().equals(methodName)) { 195  makeAccessible(method); 196                     return method; 197  } 198  } 199  } 200         return null; 201  } 202 
203     /**
204  * 改变private/protected的方法为public,尽量不调用实际改动的语句,避免JDK的SecurityManager抱怨。 205      */
206     public static void makeAccessible(Method method) { 207         if ((!Modifier.isPublic(method.getModifiers()) || !Modifier.isPublic(method.getDeclaringClass().getModifiers())) 208                 && !method.isAccessible()) { 209             method.setAccessible(true); 210  } 211  } 212 
213     /**
214  * 改变private/protected的成员变量为public,尽量不调用实际改动的语句,避免JDK的SecurityManager抱怨。 215      */
216     public static void makeAccessible(Field field) { 217         if ((!Modifier.isPublic(field.getModifiers()) || !Modifier.isPublic(field.getDeclaringClass().getModifiers()) || Modifier 218                 .isFinal(field.getModifiers())) && !field.isAccessible()) { 219             field.setAccessible(true); 220  } 221  } 222 
223     /**
224  * 通过反射, 获得Class定义中声明的泛型参数的类型, 注意泛型必须定义在父类处 225  * 如无法找到, 返回Object.class. 226  * eg. 227  * public UserDao extends HibernateDao<User> 228  * 229  * @param clazz The class to introspect 230  * @return the first generic declaration, or Object.class if cannot be determined 231      */
232     @SuppressWarnings("unchecked") 233     public static <T> Class<T> getClassGenricType(final Class clazz) { 234         return getClassGenricType(clazz, 0); 235  } 236 
237     /**
238  * 通过反射, 获得Class定义中声明的父类的泛型参数的类型. 239  * 如无法找到, 返回Object.class. 240  * 241  * 如public UserDao extends HibernateDao<User,Long> 242  * 243  * @param clazz clazz The class to introspect 244  * @param index the Index of the generic ddeclaration,start from 0. 245  * @return the index generic declaration, or Object.class if cannot be determined 246      */
247     public static Class getClassGenricType(final Class clazz, final int index) { 248 
249         Type genType = clazz.getGenericSuperclass(); 250 
251         if (!(genType instanceof ParameterizedType)) { 252             logger.warn(clazz.getSimpleName() + "'s superclass not ParameterizedType"); 253             return Object.class; 254  } 255 
256         Type[] params = ((ParameterizedType) genType).getActualTypeArguments(); 257 
258         if (index >= params.length || index < 0) { 259             logger.warn("Index: " + index + ", Size of " + clazz.getSimpleName() + "'s Parameterized Type: "
260                     + params.length); 261             return Object.class; 262  } 263         if (!(params[index] instanceof Class)) { 264             logger.warn(clazz.getSimpleName() + " not set the actual class on superclass generic parameter"); 265             return Object.class; 266  } 267 
268         return (Class) params[index]; 269  } 270     
271     public static Class<?> getUserClass(Object instance) { 272         Assert.notNull(instance, "Instance must not be null"); 273         Class clazz = instance.getClass(); 274         if (clazz != null && clazz.getName().contains(CGLIB_CLASS_SEPARATOR)) { 275             Class<?> superClass = clazz.getSuperclass(); 276             if (superClass != null && !Object.class.equals(superClass)) { 277                 return superClass; 278  } 279  } 280         return clazz; 281 
282  } 283     
284     /**
285  * 将反射时的checked exception转换为unchecked exception. 286      */
287     public static RuntimeException convertReflectionExceptionToUnchecked(Exception e) { 288         if (e instanceof IllegalAccessException || e instanceof IllegalArgumentException 289                 || e instanceof NoSuchMethodException) { 290             return new IllegalArgumentException(e); 291         } else if (e instanceof InvocationTargetException) { 292             return new RuntimeException(((InvocationTargetException) e).getTargetException()); 293         } else if (e instanceof RuntimeException) { 294             return (RuntimeException) e; 295  } 296         return new RuntimeException("Unexpected Checked Exception.", e); 297  } 298 }

 

 

转载请注明出处!

http://www.cnblogs.com/libingbin/

感谢您的阅读。如果文章对您有用,那么请轻轻点个赞,以资鼓励。

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM