反射工具类
反射工具类
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 }
--------------------------------------
勿忘初心 方得始终
--------------------------------------