反射工具类

反射工具类

  1 /**
  2  * <html>
  3  * <body>
  4  *  <P> Copyright 1994 JsonInternational</p>
  5  *  <p> All rights reserved.</p>
  6  *  <p> Created on 19941115</p>
  7  *  <p> Created by Jason</p>
  8  *  </body>
  9  * </html>
 10  */
 11 package cn.ucaner.alpaca.framework.utils.reflection;
 12 
 13 import java.lang.reflect.Field;
 14 import java.lang.reflect.InvocationTargetException;
 15 import java.lang.reflect.Method;
 16 import java.lang.reflect.ParameterizedType;
 17 import java.lang.reflect.Type;
 18 
 19 import org.apache.commons.lang3.StringUtils;
 20 import org.slf4j.Logger;
 21 import org.slf4j.LoggerFactory;
 22 
 23 /**
 24 * @Package:cn.ucaner.framework.utils   
 25 * @ClassName:ReflectionUtils   
 26 * @Description:   <p> 反射工具类.</p>
 27 * @Author: - Jason 
 28 * @CreatTime:2017年8月30日 下午2:08:28   
 29 * @Modify By:   
 30 * @ModifyTime:  
 31 * @Modify marker:   
 32 * @version    V1.0
 33  */
 34 public class ReflectionUtils {
 35     private static Logger logger = LoggerFactory.getLogger(ReflectionUtils.class);
 36 
 37     /**
 38      * 调用Getter方法.
 39      */
 40     public static Object invokeGetterMethod(Object obj, String propertyName) {
 41         String getterMethodName = "get" + StringUtils.capitalize(propertyName);
 42         return invokeMethod(obj, getterMethodName, new Class[] {}, new Object[] {});
 43     }
 44 
 45     /**
 46      * 调用Setter方法.使用value的Class来查找Setter方法.
 47      */
 48     public static void invokeSetterMethod(Object obj, String propertyName, Object value) {
 49         invokeSetterMethod(obj, propertyName, value, null);
 50     }
 51 
 52     /**
 53      * 调用Setter方法.
 54      * @param propertyType   用于查找Setter方法,为空时使用value的Class替代.
 55      */
 56     public static void invokeSetterMethod(Object obj, String propertyName, Object value, Class<?> propertyType) {
 57         Class<?> type = propertyType != null ? propertyType : value.getClass();
 58         String setterMethodName = "set" + StringUtils.capitalize(propertyName);
 59         invokeMethod(obj, setterMethodName, new Class[] { type }, new Object[] { value });
 60     }
 61 
 62     /**
 63      * 直接读取对象属性值, 无视private/protected修饰符, 不经过getter函数.
 64      */
 65     public static Object getFieldValue(final Object obj, final String fieldName) {
 66         Field field = getAccessibleField(obj, fieldName);
 67 
 68         if (field == null) {
 69             throw new IllegalArgumentException("Could not find field [" + fieldName + "] on target [" + obj + "]");
 70         }
 71 
 72         Object result = null;
 73         try {
 74             result = field.get(obj);
 75         } catch (IllegalAccessException e) {
 76             logger.error("不可能抛出的异常{}", e.getMessage());
 77         }
 78         return result;
 79     }
 80 
 81     /**
 82      * 直接设置对象属性值, 无视private/protected修饰符, 不经过setter函数.
 83      */
 84     public static void setFieldValue(final Object obj, final String fieldName, final Object value) {
 85         Field field = getAccessibleField(obj, fieldName);
 86 
 87         if (field == null) {
 88             throw new IllegalArgumentException("Could not find field [" + fieldName + "] on target [" + obj + "]");
 89         }
 90 
 91         try {
 92             field.set(obj, value);
 93         } catch (IllegalAccessException e) {
 94             logger.error("不可能抛出的异常:{}", e.getMessage());
 95         }
 96     }
 97 
 98     /**
 99      * 循环向上转型, 获取对象的DeclaredField, 并强制设置为可访问.
100      * 如向上转型到Object仍无法找到, 返回null.
101      */
102     public static Field getAccessibleField(final Object obj, final String fieldName) {
103         if (obj == null) {
104             logger.error("ReflectionUtil.getAccessibleField(final Object obj, final String fieldName)的obj参数不能为空");
105             throw new NullPointerException("object不能为空");
106         }
107         if (StringUtils.isBlank(fieldName)) {
108             logger.error("ReflectionUtil.getAccessibleField(final Object obj, final String fieldName)的fieldName参数不能为空");
109             throw new NullPointerException("fieldName不能为空");
110         }
111         for (Class<?> superClass = obj.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()) {
112             try {
113                 Field field = superClass.getDeclaredField(fieldName);
114                 field.setAccessible(true);
115                 return field;
116             } catch (NoSuchFieldException e) {
117                 // NOSONAR
118                 // Field不在当前类定义,继续向上转型
119                 logger.error("NoSuchFieldException!");
120             }
121         }
122         return null;
123     }
124 
125     /**
126      * 直接调用对象方法, 无视private/protected修饰符. 用于一次性调用的情况.
127      */
128     public static Object invokeMethod(final Object obj, final String methodName, final Class<?>[] parameterTypes, final Object[] args) {
129         Method method = getAccessibleMethod(obj, methodName, parameterTypes);
130         if (method == null) {
131             throw new IllegalArgumentException("Could not find method [" + methodName + "] on target [" + obj + "]");
132         }
133 
134         try {
135             return method.invoke(obj, args);
136         } catch (Exception e) {
137             throw convertReflectionExceptionToUnchecked(e);
138         }
139     }
140 
141     /**
142      * 循环向上转型, 获取对象的DeclaredMethod,并强制设置为可访问. 如向上转型到Object仍无法找到, 返回null.
143      * 用于方法需要被多次调用的情况. 先使用本函数先取得Method,然后调用Method.invoke
144      * (Object obj, Object...args)
145      */
146     public static Method getAccessibleMethod(final Object obj, final String methodName, final Class<?>... parameterTypes) {
147         if (obj == null) {
148             logger.error("ReflectionUtil.getAccessibleField(final Object obj, final String fieldName)的obj参数不能为空");
149             throw new NullPointerException("object不能为空");
150         }
151 
152         for (Class<?> superClass = obj.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()) {
153             try {
154                 Method method = superClass.getDeclaredMethod(methodName, parameterTypes);
155                 method.setAccessible(true);
156                 return method;
157 
158             } catch (NoSuchMethodException e) {
159                 // Method不在当前类定义,继续向上转型
160                 logger.error("NoSuchMethodException!", e);
161             }
162         }
163         return null;
164     }
165 
166     /**
167      * 通过反射, 获得Class定义中声明的父类的泛型参数的类型. 如无法找到, 返回Object.class. eg. public UserDao
168      * extends HibernateDao<User>
169      * @param clazz The class to introspect
170      * @return the first generic declaration, or Object.class if cannot be determined
171      */
172     @SuppressWarnings("unchecked")
173     public static <T> Class<T> getSuperClassGenricType(final Class clazz) {
174         return getSuperClassGenricType(clazz, 0);
175     }
176 
177     /**
178      * 通过反射, 获得Class定义中声明的父类的泛型参数的类型. 如无法找到, 返回Object.class.
179      * 如public UserDao extends HibernateDao<User,Long>
180      * @param clazz clazz The class to introspect
181      * @param index the Index of the generic ddeclaration,start from 0.
182      * @return the index generic declaration, or Object.class if cannot be determined
183      */
184     public static Class getSuperClassGenricType(final Class clazz, final int index) {
185 
186         Type genType = clazz.getGenericSuperclass();
187 
188         if (!(genType instanceof ParameterizedType)) {
189             logger.warn(clazz.getSimpleName() + "'s superclass not ParameterizedType");
190             return Object.class;
191         }
192 
193         Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
194 
195         if (index >= params.length || index < 0) {
196             logger.warn("Index: " + index + ", Size of " + clazz.getSimpleName() + "'s Parameterized Type: " + params.length);
197             return Object.class;
198         }
199         if (!(params[index] instanceof Class)) {
200             logger.warn(clazz.getSimpleName() + " not set the actual class on superclass generic parameter");
201             return Object.class;
202         }
203 
204         return (Class) params[index];
205     }
206 
207     /**
208      * 将反射时的checked exception转换为unchecked exception.
209      */
210     public static RuntimeException convertReflectionExceptionToUnchecked(Exception e) {
211         if (e instanceof IllegalAccessException || e instanceof IllegalArgumentException || e instanceof NoSuchMethodException) {
212             return new IllegalArgumentException("Reflection Exception.", e);
213         } else if (e instanceof InvocationTargetException) {
214             return new RuntimeException("Reflection Exception.", ((InvocationTargetException) e).getTargetException());
215         } else if (e instanceof RuntimeException) {
216             return (RuntimeException) e;
217         }
218         return new RuntimeException("Unexpected Checked Exception.", e);
219     }
220 }

 

posted @ 2018-06-14 20:25  安以北往南  阅读(268)  评论(0编辑  收藏  举报