• 反射工具类


    反射工具类

      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 }
  • 相关阅读:
    十一.状态设计模式
    十. 享元设计模式
    Orcale(一)概念
    java类加载器
    spring中的事务管理机制
    spring中的annotation注解类配置
    countDownLatch和Semaphore用于多线程
    布隆过滤器
    mybatis-genator自动生成的mapper中模糊查询使用方法
    java中的异常
  • 原文地址:https://www.cnblogs.com/jasonandy/p/9184840.html
Copyright © 2020-2023  润新知