博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
反射工具类.提供调用getter/setter方法, 访问私有变量, 调用私有方法, 获取泛型类型Class,被AOP过的真实类等工具函数.java...
阅读量:6552 次
发布时间:2019-06-24

本文共 14588 字,大约阅读时间需要 48 分钟。

1 import org.apache.commons.lang3.StringUtils;  2 import org.apache.commons.lang3.Validate;  3 import org.apache.poi.ss.formula.functions.T;  4 import org.slf4j.Logger;  5 import org.slf4j.LoggerFactory;  6   7 import java.lang.reflect.*;  8 import java.util.HashMap;  9 import java.util.Map; 10  11 /** 12  * ClassName: Reflections 13  * @Description: 反射工具类.提供调用getter/setter方法, 访问私有变量, 调用私有方法, 获取泛型类型Class,被AOP过的真实类等工具函数. 14  * @author 15  * @date 2015年9月9日 下午1:02:26 16  */ 17 public class Reflections { 18     private static final String SETTER_PREFIX = "set"; 19  20     private static final String GETTER_PREFIX = "get"; 21  22     private static final String CGLIB_CLASS_SEPARATOR = "$$"; 23  24     private static Logger logger = LoggerFactory.getLogger(Reflections.class); 25  26     /** 27      * @Description: 调用Getter方法. 28      * @param obj 29      * @param propertyName 30      * @return    31      * @return Object   32      * @throws 33      * @author feifei.liu 34      * @date 2015年9月25日 下午7:55:46 35      */ 36     public static Object invokeGetter(Object obj, String propertyName) { 37         String getterMethodName = GETTER_PREFIX + StringUtils.capitalize(propertyName); 38         return invokeMethod(obj, getterMethodName, new Class[] {}, new Object[] {}); 39     } 40  41     /** 42      * @Description: 调用Setter方法, 仅匹配方法名。 43      * @param obj 44      * @param propertyName 45      * @param value    46      * @return void   47      * @throws 48      * @author feifei.liu 49      * @date 2015年9月25日 下午7:55:59 50      */ 51     public static void invokeSetter(Object obj, String propertyName, Object value) { 52         String setterMethodName = SETTER_PREFIX + StringUtils.capitalize(propertyName); 53         invokeMethodByName(obj, setterMethodName, new Object[] { value }); 54     } 55  56     /** 57      * @Description: 直接读取对象属性值, 无视private/protected修饰符, 不经过getter函数. 58      * @param obj 59      * @param fieldName 60      * @return    61      * @return Object   62      * @throws 63      * @author feifei.liu 64      * @date 2015年9月25日 下午7:56:13 65      */ 66     public static Object getFieldValue(final Object obj, final String fieldName) { 67         Field field = getAccessibleField(obj, fieldName); 68  69         if (field == null) { 70             throw new IllegalArgumentException("Could not find field [" + fieldName + "] on target [" + obj + "]"); 71         } 72  73         Object result = null; 74         try { 75             result = field.get(obj); 76         } catch (IllegalAccessException e) { 77             logger.error("不可能抛出的异常{}", e.getMessage()); 78         } 79         return result; 80     } 81  82     /** 83      * @Description: 直接设置对象属性值, 无视private/protected修饰符, 不经过setter函数. 84      * @param obj 85      * @param fieldName 86      * @param value    87      * @return void   88      * @throws 89      * @author feifei.liu 90      * @date 2015年9月25日 下午7:56:26 91      */ 92     public static void setFieldValue(final Object obj, final String fieldName, final Object value) { 93         Field field = getAccessibleField(obj, fieldName); 94  95         if (field == null) { 96             throw new IllegalArgumentException("Could not find field [" + fieldName + "] on target [" + obj + "]"); 97         } 98  99         try {100             /*if("false".equals(value) || "true".equals(value)){101                 Boolean b = new Boolean(value.toString());102                 boolean b1 = b.booleanValue();103                 field.set(obj, b1);104             }else{105                 field.set(obj, value);106             }*/107             field.set(obj, value);108         } catch (IllegalAccessException e) {109             logger.error("不可能抛出的异常:{}", e.getMessage());110         }111     }112 113     /**114      * @Description: 直接调用对象方法, 无视private/protected修饰符.115      *                   用于一次性调用的情况,否则应使用getAccessibleMethod()函数获得Method后反复调用. 同时匹配方法名+参数类型.116      * @param obj117      * @param methodName118      * @param parameterTypes119      * @param args120      * @return   121      * @return Object  122      * @throws123      * @author feifei.liu124      * @date 2015年9月25日 下午7:56:33125      */126     public static Object invokeMethod(final Object obj, final String methodName, final Class
[] parameterTypes,127 final Object[] args) {128 Method method = getAccessibleMethod(obj, methodName, parameterTypes);129 if (method == null) {130 throw new IllegalArgumentException("Could not find method [" + methodName + "] on target [" + obj + "]");131 }132 133 try {134 return method.invoke(obj, args);135 } catch (Exception e) {136 throw convertReflectionExceptionToUnchecked(e);137 }138 }139 140 /**141 * @Description: 直接调用对象方法, 无视private/protected修饰符,142 * 用于一次性调用的情况,否则应使用getAccessibleMethodByName()函数获得Method后反复调用.143 * 只匹配函数名,如果有多个同名函数调用第一个.144 * @param obj145 * @param methodName146 * @param args147 * @return 148 * @return Object 149 * @throws150 * @author feifei.liu151 * @date 2015年9月25日 下午7:56:57152 */153 public static Object invokeMethodByName(final Object obj, final String methodName, final Object[] args) {154 Method method = getAccessibleMethodByName(obj, methodName);155 if (method == null) {156 throw new IllegalArgumentException("Could not find method [" + methodName + "] on target [" + obj + "]");157 }158 159 try {160 return method.invoke(obj, args);161 } catch (Exception e) {162 throw convertReflectionExceptionToUnchecked(e);163 }164 }165 166 /**167 * @Description: 循环向上转型, 获取对象的DeclaredField, 并强制设置为可访问.168 * 如向上转型到Object仍无法找到, 返回null.169 * @param obj170 * @param fieldName171 * @return 172 * @return Field 173 * @throws174 * @author feifei.liu175 * @date 2015年9月25日 下午7:57:39176 */177 public static Field getAccessibleField(final Object obj, final String fieldName) {178 Validate.notNull(obj, "object can't be null");179 Validate.notBlank(fieldName, "fieldName can't be blank");180 for (Class
superClass = obj.getClass(); superClass != Object.class; superClass = superClass181 .getSuperclass()) {182 try {183 Field field = superClass.getDeclaredField(fieldName);184 makeAccessible(field);185 return field;186 } catch (NoSuchFieldException e) {
// NOSONAR187 // Field不在当前类定义,继续向上转型188 }189 }190 return null;191 }192 193 /**194 * @Description: 循环向上转型, 获取对象的DeclaredMethod,并强制设置为可访问. 如向上转型到Object仍无法找到, 返回null.195 * 匹配函数名+参数类型.196 * 用于方法需要被多次调用的情况. 先使用本函数先取得Method,然后调用Method.invoke(Object obj, Object...args).197 * @param obj198 * @param methodName199 * @param parameterTypes200 * @return 201 * @return Method 202 * @throws203 * @author feifei.liu204 * @date 2015年9月25日 下午7:57:57205 */206 public static Method getAccessibleMethod(final Object obj, final String methodName,207 final Class
... parameterTypes) {208 Validate.notNull(obj, "object can't be null");209 Validate.notBlank(methodName, "methodName can't be blank");210 211 for (Class
searchType = obj.getClass(); searchType != Object.class; searchType = searchType212 .getSuperclass()) {213 try {214 Method method = searchType.getDeclaredMethod(methodName, parameterTypes);215 makeAccessible(method);216 return method;217 } catch (NoSuchMethodException e) {218 // Method不在当前类定义,继续向上转型219 }220 }221 return null;222 }223 224 /**225 * @Description: 循环向上转型, 获取对象的DeclaredMethod,并强制设置为可访问. 如向上转型到Object仍无法找到, 返回null. 只匹配函数名.226 * 用于方法需要被多次调用的情况. 先使用本函数先取得Method,然后调用Method.invoke(Object obj, Object...args)227 * @param obj228 * @param methodName229 * @return 230 * @return Method 231 * @throws232 * @author feifei.liu233 * @date 2015年9月25日 下午7:58:48234 */235 public static Method getAccessibleMethodByName(final Object obj, final String methodName) {236 Validate.notNull(obj, "object can't be null");237 Validate.notBlank(methodName, "methodName can't be blank");238 239 for (Class
searchType = obj.getClass(); searchType != Object.class; searchType = searchType240 .getSuperclass()) {241 Method[] methods = searchType.getDeclaredMethods();242 for (Method method : methods) {243 if (method.getName().equals(methodName)) {244 makeAccessible(method);245 return method;246 }247 }248 }249 return null;250 }251 252 /**253 * @Description: 改变private/protected的方法为public,尽量不调用实际改动的语句,避免JDK的SecurityManager抱怨254 * @param method 255 * @return void 256 * @throws257 * @author feifei.liu258 * @date 2015年9月25日 下午7:59:24259 */260 public static void makeAccessible(Method method) {261 if ((!Modifier.isPublic(method.getModifiers()) || !Modifier.isPublic(method.getDeclaringClass().getModifiers()))262 && !method.isAccessible()) {263 method.setAccessible(true);264 }265 }266 267 /**268 * @Description: 改变private/protected的成员变量为public,尽量不调用实际改动的语句,避免JDK的SecurityManager抱怨269 * @param field 270 * @return void 271 * @throws272 * @author feifei.liu273 * @date 2015年9月25日 下午7:59:40274 */275 public static void makeAccessible(Field field) {276 if ((!Modifier.isPublic(field.getModifiers()) || !Modifier.isPublic(field.getDeclaringClass().getModifiers())277 || Modifier.isFinal(field.getModifiers())) && !field.isAccessible()) {278 field.setAccessible(true);279 }280 }281 282 /**283 * @Description: 通过反射, 获得Class定义中声明的泛型参数的类型, 注意泛型必须定义在父类处 如无法找到, 返回Object.class. eg.284 * @param clazz285 * @return 286 * @return Class
287 * @throws288 * @author feifei.liu289 * @date 2015年9月25日 下午7:59:53290 */291 @SuppressWarnings({ "unchecked", "rawtypes" })292 public static
Class
getClassGenricType(final Class clazz) {293 return getClassGenricType(clazz, 0);294 }295 296 /**297 * @Description: 通过反射, 获得Class定义中声明的父类的泛型参数的类型. 如无法找到, 返回Object.class.298 * @param clazz299 * @param index300 * @return 301 * @return Class 302 * @throws303 * @author feifei.liu304 * @date 2015年9月25日 下午8:00:07305 */306 @SuppressWarnings("rawtypes")307 public static Class getClassGenricType(final Class clazz, final int index) {308 309 Type genType = clazz.getGenericSuperclass();310 311 if (!(genType instanceof ParameterizedType)) {312 logger.warn(clazz.getSimpleName() + "'s superclass not ParameterizedType");313 return Object.class;314 }315 316 Type[] params = ((ParameterizedType) genType).getActualTypeArguments();317 318 if ((index >= params.length) || (index < 0)) {319 logger.warn("Index: " + index + ", Size of " + clazz.getSimpleName() + "'s Parameterized Type: "320 + params.length);321 return Object.class;322 }323 if (!(params[index] instanceof Class)) {324 logger.warn(clazz.getSimpleName() + " not set the actual class on superclass generic parameter");325 return Object.class;326 }327 328 return (Class) params[index];329 }330 331 /**332 * @Description: 通过反射,获得当前对象类型333 * @param instance334 * @return 335 * @return Class
336 * @throws337 * @author feifei.liu338 * @date 2015年9月25日 下午8:00:29339 */340 @SuppressWarnings("rawtypes")341 public static Class
getUserClass(Object instance) {342 Validate.notNull(instance, "Instance must not be null");343 Class clazz = instance.getClass();344 if ((clazz != null) && clazz.getName().contains(CGLIB_CLASS_SEPARATOR)) {345 Class
superClass = clazz.getSuperclass();346 if ((superClass != null) && !Object.class.equals(superClass)) {347 return superClass;348 }349 }350 return clazz;351 352 }353 354 /**355 * @Description: 将反射时的checked exception转换为unchecked exception.356 * @param e357 * @return 358 * @return RuntimeException 359 * @throws360 * @author feifei.liu361 * @date 2015年9月25日 下午8:01:08362 */363 public static RuntimeException convertReflectionExceptionToUnchecked(Exception e) {364 if ((e instanceof IllegalAccessException) || (e instanceof IllegalArgumentException)365 || (e instanceof NoSuchMethodException)) {366 return new IllegalArgumentException(e);367 } else if (e instanceof InvocationTargetException) {368 return new RuntimeException(((InvocationTargetException) e).getTargetException());369 } else if (e instanceof RuntimeException) {370 return (RuntimeException) e;371 }372 return new RuntimeException("Unexpected Checked Exception.", e);373 }374 375 /**376 * @Description: 循环向上,获取对象声明的字段377 * @author xiaopeng.ma378 * @date 2017/3/23 17:03379 */380 public static Map
getAllDeclaredField(T t) {381 Map
map = new HashMap<>();382 if (t != null) {383 Class
clazz = t.getClass();384 for (; Object.class != clazz; clazz.getSuperclass()) {385 Field[] declaredFields = clazz.getDeclaredFields();386 for (Field declaredField : declaredFields) {387 map.put(declaredField.getName(), declaredField.getClass().getSimpleName());388 }389 }390 }391 return map;392 }393 394 }

 

转载于:https://www.cnblogs.com/zhanghongjie/p/9239846.html

你可能感兴趣的文章