反射工具类源码

  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/

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

 

posted on 2016-11-02 23:46  bingbinlee  阅读(1947)  评论(0编辑  收藏  举报