packagecom.yingchao.kgou.core;importjava.lang.reflect.Field;importjava.lang.reflect.InvocationTargetException;importjava.lang.reflect.Method;importjava.lang.reflect.ParameterizedType;importjava.lang.reflect.Type;importorg.apache.commons.lang.StringUtils;importorg.slf4j.Logger;importorg.slf4j.LoggerFactory;importorg.springframework.util.Assert;/*** 反射工具类.
*
* 提供访问私有变量,获取泛型类型Class, 提取集合中元素的属性, 转换字符串到对象等Util函数.
**/
public classReflectionUtils {private static Logger logger = LoggerFactory.getLogger(ReflectionUtils.class);/*** 调用Getter方法.*/
public staticObject invokeGetterMethod(Object obj, String propertyName) {
String getterMethodName= "get" +StringUtils.capitalize(propertyName);return invokeMethod(obj, getterMethodName, new Class[] {}, newObject[] {});
}/*** 调用Setter方法.使用value的Class来查找Setter方法.*/
public static voidinvokeSetterMethod(Object obj, String propertyName, Object value) {
invokeSetterMethod(obj, propertyName, value,null);
}/*** 调用Setter方法.
*
*@parampropertyType 用于查找Setter方法,为空时使用value的Class替代.*/
public static void invokeSetterMethod(Object obj, String propertyName, Object value, Class>propertyType) {
Class> type = propertyType != null ?propertyType : value.getClass();
String setterMethodName= "set" +StringUtils.capitalize(propertyName);
invokeMethod(obj, setterMethodName,new Class[] { type }, newObject[] { value });
}/*** 直接读取对象属性值, 无视private/protected修饰符, 不经过getter函数.*/
public static Object getFieldValue(final Object obj, finalString fieldName) {
Field field=getAccessibleField(obj, fieldName);if (field == null) {throw new IllegalArgumentException("Could not find field [" + fieldName + "] on target [" + obj + "]");
}
Object result= null;try{
result=field.get(obj);
}catch(IllegalAccessException e) {
logger.error("不可能抛出的异常{}", e.getMessage());
}returnresult;
}/*** 直接设置对象属性值, 无视private/protected修饰符, 不经过setter函数.*/
public static void setFieldValue(final Object obj, final String fieldName, finalObject value) {
Field field=getAccessibleField(obj, fieldName);if (field == null) {throw new IllegalArgumentException("Could not find field [" + fieldName + "] on target [" + obj + "]");
}try{
field.set(obj, value);
}catch(IllegalAccessException e) {
logger.error("不可能抛出的异常:{}", e.getMessage());
}
}/*** 循环向上转型, 获取对象的DeclaredField, 并强制设置为可访问.
*
* 如向上转型到Object仍无法找到, 返回null.*/
public static Field getAccessibleField(final Object obj, finalString fieldName) {
Assert.notNull(obj,"object不能为空");
Assert.hasText(fieldName,"fieldName");for (Class> superClass = obj.getClass(); superClass != Object.class; superClass =superClass.getSuperclass()) {try{
Field field=superClass.getDeclaredField(fieldName);
field.setAccessible(true);returnfield;
}catch (NoSuchFieldException e) {//NOSONAR//Field不在当前类定义,继续向上转型
}
}return null;
}/*** 直接调用对象方法, 无视private/protected修饰符.
* 用于一次性调用的情况.*/
public static Object invokeMethod(final Object obj, final String methodName, final Class>[] parameterTypes,finalObject[] args) {
Method method=getAccessibleMethod(obj, methodName, parameterTypes);if (method == null) {throw new IllegalArgumentException("Could not find method [" + methodName + "] on target [" + obj + "]");
}try{returnmethod.invoke(obj, args);
}catch(Exception e) {throwconvertReflectionExceptionToUnchecked(e);
}
}/*** 循环向上转型, 获取对象的DeclaredMethod,并强制设置为可访问.
* 如向上转型到Object仍无法找到, 返回null.
*
* 用于方法需要被多次调用的情况. 先使用本函数先取得Method,然后调用Method.invoke(Object obj, Object... args)*/
public static Method getAccessibleMethod(final Object obj, finalString methodName,final Class>... parameterTypes) {
Assert.notNull(obj,"object不能为空");for (Class> superClass = obj.getClass(); superClass != Object.class; superClass =superClass.getSuperclass()) {try{
Method method=superClass.getDeclaredMethod(methodName, parameterTypes);
method.setAccessible(true);returnmethod;
}catch (NoSuchMethodException e) {//NOSONAR//Method不在当前类定义,继续向上转型
}
}return null;
}/*** 通过反射, 获得Class定义中声明的父类的泛型参数的类型.
* 如无法找到, 返回Object.class.
* eg.
* public UserDao extends HibernateDao
*
*@paramclazz The class to introspect
*@returnthe first generic declaration, or Object.class if cannot be determined*/@SuppressWarnings({"unchecked", "rawtypes"})public static Class getSuperClassGenricType(finalClass clazz) {return getSuperClassGenricType(clazz, 0);
}/*** 通过反射, 获得Class定义中声明的父类的泛型参数的类型.
* 如无法找到, 返回Object.class.
*
* 如public UserDao extends HibernateDao
*
*@paramclazz clazz The class to introspect
*@paramindex the Index of the generic ddeclaration,start from 0.
*@returnthe index generic declaration, or Object.class if cannot be determined*/@SuppressWarnings("rawtypes")public static Class getSuperClassGenricType(final Class clazz, final intindex) {
Type genType=clazz.getGenericSuperclass();if (!(genType instanceofParameterizedType)) {
logger.warn(clazz.getSimpleName()+ "'s superclass not ParameterizedType");return Object.class;
}
Type[] params=((ParameterizedType) genType).getActualTypeArguments();if (index >= params.length || index < 0) {
logger.warn("Index: " + index + ", Size of " + clazz.getSimpleName() + "'s Parameterized Type: "
+params.length);return Object.class;
}if (!(params[index] instanceofClass)) {
logger.warn(clazz.getSimpleName()+ " not set the actual class on superclass generic parameter");return Object.class;
}return(Class) params[index];
}/*** 将反射时的checked exception转换为unchecked exception.*/
public staticRuntimeException convertReflectionExceptionToUnchecked(Exception e) {if (e instanceof IllegalAccessException || e instanceofIllegalArgumentException|| e instanceofNoSuchMethodException) {return new IllegalArgumentException("Reflection Exception.", e);
}else if (e instanceofInvocationTargetException) {return new RuntimeException("Reflection Exception.", ((InvocationTargetException) e).getTargetException());
}else if (e instanceofRuntimeException) {return(RuntimeException) e;
}return new RuntimeException("Unexpected Checked Exception.", e);
}
}