import java.lang.reflect.*;/*** 反射工具类.* * 提供调用getter/setter方法, 访问私有变量, 调用私有方法, 获取泛型类型Class, 被AOP过的真实类等工具函数.* * @author caidongqu*/
public class Reflections {private static final String SETTER_PREFIX = "set";private static final String GETTER_PREFIX = "get";private static final String CGLIB_CLASS_SEPARATOR = "$$";private static Logger logger = LoggerFactory.getLogger(Reflections.class);/*** 调用Getter方法.*/public static Object invokeGetter(Object obj, String propertyName) {String getterMethodName = GETTER_PREFIX + StringUtils.capitalize(propertyName);return invokeMethod(obj, getterMethodName, new Class[] {}, new Object[] {});}/*** 调用Setter方法, 仅匹配方法名。*/public static void invokeSetter(Object obj, String propertyName, Object value) {String setterMethodName = SETTER_PREFIX + StringUtils.capitalize(propertyName);invokeMethodByName(obj, setterMethodName, new Object[] { value });}/*** 直接读取对象属性值, 无视private/protected修饰符, 不经过getter函数.*/public static Object getFieldValue(final Object obj, final String 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());}return result;}/*** 直接设置对象属性值, 无视private/protected修饰符, 不经过setter函数.*/public static void setFieldValue(final Object obj, final String fieldName, final Object 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());}}/*** 直接调用对象方法, 无视private/protected修饰符.* 用于一次性调用的情况,否则应使用getAccessibleMethod()函数获得Method后反复调用.* 同时匹配方法名+参数类型,*/public static Object invokeMethod(final Object obj, final String methodName, final Class<?>[] parameterTypes,final Object[] args) {Method method = getAccessibleMethod(obj, methodName, parameterTypes);if (method == null) {throw new IllegalArgumentException("Could not find method [" + methodName + "] on target [" + obj + "]");}try {return method.invoke(obj, args);} catch (Exception e) {throw convertReflectionExceptionToUnchecked(e);}}/*** 直接调用对象方法, 无视private/protected修饰符,* 用于一次性调用的情况,否则应使用getAccessibleMethodByName()函数获得Method后反复调用.* 只匹配函数名,如果有多个同名函数调用第一个。*/public static Object invokeMethodByName(final Object obj, final String methodName, final Object[] args) {Method method = getAccessibleMethodByName(obj, methodName);if (method == null) {throw new IllegalArgumentException("Could not find method [" + methodName + "] on target [" + obj + "]");}try {return method.invoke(obj, args);} catch (Exception e) {throw convertReflectionExceptionToUnchecked(e);}}/*** 循环向上转型, 获取对象的DeclaredField, 并强制设置为可访问.* * 如向上转型到Object仍无法找到, 返回null.*/public static Field getAccessibleField(final Object obj, final String fieldName) {AssertUtil.notNull(obj, "object can't be null");AssertUtil.notBlank(fieldName, "fieldName can't be blank");for (Class<?> superClass = obj.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()) {try {Field field = superClass.getDeclaredField(fieldName);makeAccessible(field);return field;} catch (NoSuchFieldException e) {//NOSONAR// Field不在当前类定义,继续向上转型}}return null;}/*** 循环向上转型, 获取对象的DeclaredMethod,并强制设置为可访问.* 如向上转型到Object仍无法找到, 返回null.* 匹配函数名+参数类型。* * 用于方法需要被多次调用的情况. 先使用本函数先取得Method,然后调用Method.invoke(Object obj, Object... args)*/public static Method getAccessibleMethod(final Object obj, final String methodName,final Class<?>... parameterTypes) {AssertUtil.notNull(obj, "object can't be null");AssertUtil.notBlank(methodName, "methodName can't be blank");for (Class<?> searchType = obj.getClass(); searchType != Object.class; searchType = searchType.getSuperclass()) {try {Method method = searchType.getDeclaredMethod(methodName, parameterTypes);makeAccessible(method);return method;} catch (NoSuchMethodException e) {// Method不在当前类定义,继续向上转型}}return null;}/*** 循环向上转型, 获取对象的DeclaredMethod,并强制设置为可访问.* 如向上转型到Object仍无法找到, 返回null.* 只匹配函数名。* * 用于方法需要被多次调用的情况. 先使用本函数先取得Method,然后调用Method.invoke(Object obj, Object... args)*/public static Method getAccessibleMethodByName(final Object obj, final String methodName) {AssertUtil.notNull(obj, "object can't be null");AssertUtil.notBlank(methodName, "methodName can't be blank");for (Class<?> searchType = obj.getClass(); searchType != Object.class; searchType = searchType.getSuperclass()) {Method[] methods = searchType.getDeclaredMethods();for (Method method : methods) {if (method.getName().equals(methodName)) {makeAccessible(method);return method;}}}return null;}/*** 改变private/protected的方法为public,尽量不调用实际改动的语句,避免JDK的SecurityManager抱怨。*/public static void makeAccessible(Method method) {if ((!Modifier.isPublic(method.getModifiers()) || !Modifier.isPublic(method.getDeclaringClass().getModifiers()))&& !method.isAccessible()) {method.setAccessible(true);}}/*** 改变private/protected的成员变量为public,尽量不调用实际改动的语句,避免JDK的SecurityManager抱怨。*/public static void makeAccessible(Field field) {if ((!Modifier.isPublic(field.getModifiers()) || !Modifier.isPublic(field.getDeclaringClass().getModifiers()) || Modifier.isFinal(field.getModifiers())) && !field.isAccessible()) {field.setAccessible(true);}}/*** 通过反射, 获得Class定义中声明的泛型参数的类型, 注意泛型必须定义在父类处* 如无法找到, 返回Object.class.* eg.* public UserDao extends HibernateDao<User>** @param clazz The class to introspect* @return the first generic declaration, or Object.class if cannot be determined*/@SuppressWarnings({ "unchecked", "rawtypes" })public static <T> Class<T> getClassGenricType(final Class clazz) {return getClassGenricType(clazz, 0);}/*** 通过反射, 获得Class定义中声明的父类的泛型参数的类型.* 如无法找到, 返回Object.class.* * 如public UserDao extends HibernateDao<User,Long>** @param clazz clazz The class to introspect* @param index the Index of the generic ddeclaration,start from 0.* @return the index generic declaration, or Object.class if cannot be determined*/@SuppressWarnings("rawtypes")public static Class getClassGenricType(final Class clazz, final int index) {Type genType = clazz.getGenericSuperclass();if (!(genType instanceof ParameterizedType)) {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] instanceof Class)) {logger.warn(clazz.getSimpleName() + " not set the actual class on superclass generic parameter");return Object.class;}return (Class) params[index];}@SuppressWarnings("rawtypes")public static Class<?> getUserClass(Object instance) {if(instance == null)throw new RuntimeException("Instance must not be null");Class clazz = instance.getClass();if (clazz != null && clazz.getName().contains(CGLIB_CLASS_SEPARATOR)) {Class<?> superClass = clazz.getSuperclass();if (superClass != null && !Object.class.equals(superClass)) {return superClass;}}return clazz;}/*** 将反射时的checked exception转换为unchecked exception.*/public static RuntimeException convertReflectionExceptionToUnchecked(Exception e) {if (e instanceof IllegalAccessException || e instanceof IllegalArgumentException|| e instanceof NoSuchMethodException) {return new IllegalArgumentException(e);} else if (e instanceof InvocationTargetException) {return new RuntimeException(((InvocationTargetException) e).getTargetException());} else if (e instanceof RuntimeException) {return (RuntimeException) e;}return new RuntimeException("Unexpected Checked Exception.", e);}
}

反射工具类Reflections相关推荐

  1. Java反射工具:Reflections

    反射作为Java的高级特性之一,通过它,我们可以在程序的运行期间动态地去操作类的属性或方法.相比于直接调用,反射调用的执行速度会偏慢,所以不建议在常规的业务代码中使用.但是因其灵活性和扩展性比较高,往 ...

  2. 反射工具类 java_Java反射工具类

    importjava.lang.reflect.Field;importjava.lang.reflect.Method;/*** Java反射工具类 * 提供以下几个功能: * 1. 取最简类名 * ...

  3. 【Android 插件化】Hook 插件化框架 ( 反射工具类 | 反射常用操作整理 )

    Android 插件化系列文章目录 [Android 插件化]插件化简介 ( 组件化与插件化 ) [Android 插件化]插件化原理 ( JVM 内存数据 | 类加载流程 ) [Android 插件 ...

  4. 反射工具类ReflectionUtils

    为什么80%的码农都做不了架构师?>>>    package net.pm.common.toolkit;import java.lang.reflect.Field; impor ...

  5. 反射工具类,如斯优雅

    Foreword 反射的作用我在这就不多说了,每次用到反射都是那么一坨代码丢进去,总是让人觉得很不优雅,如今有了我这个反射工具类,那么大家就可以一句话优雅地来完成反射的工作,该工具类是站在 jOOR ...

  6. 【java reflection】反射工具类总结

    这段时间公司搞封闭开发,做一个联通总部的客服系统项目,是基于springboot的.在开发工程中遇到一个页面datagrid数据排序的功能,因为有多个表的数据都要用到排序功能,于是我就写了一个排序功能 ...

  7. java根据属性获取对象_java反射工具类--通过指定属性名,获取/设置对象属性值

    java对象通过点运算符操作对象属性的方式没法使用for,while等循环,此工具主要解决这一问题. 例如:有一对象包含属性有一定规律 obj1: { name1: "张三", a ...

  8. java 反射 接口工具类_Java 反射工具类 ReflectionUtils

    import lombok.extern.slf4j.Slf4j; import java.lang.reflect.*; /** * 反射的 Utils 函数集合 * 提供访问私有变量, 获取泛型类 ...

  9. commons-lang3-3.2.jar中的常用工具类的使用

    这个包中的很多工具类可以简化我们的操作,在这里简单的研究其中的几个工具类的使用. 1.StringUtils工具类 可以判断是否是空串,是否为null,默认值设置等操作: /*** StringUti ...

最新文章

  1. 深度学习准「研究僧」预习资料:图灵奖得主Yann LeCun《深度学习(Pytorch)》春季课程...
  2. bst latex 最大作者数_latex bst文件怎么用
  3. linux redis 三种启动方式
  4. leetcode算法题--不同路径
  5. 42、Power Query-Text.Remove函数应用
  6. MySQL 插入、更新、删除、简单检索
  7. git 常用别名设置
  8. angular项目打包_vue项目部署的最佳实践
  9. 利用Linq在RadCombobox中输出分类后的数据
  10. QPW 企业员工表(tf_company_employee)
  11. pthread_cleanup_push与pthread_cleanup_pop的目的 作用
  12. C语言编辑飘扬的红旗代码,C语言 飘动的红旗(要有旗杆)
  13. 数据可视化工具软件哪个最好
  14. Windows10下编译Nginx源码
  15. Vue-CLI 4 搭建Vue项目
  16. 台式计算机为什么数字输入不了,计算机键盘无法输入数字,为什么?
  17. 华硕笔记本提示android,华硕主板电脑和华硕笔记本开启VT进BIOS设置方法教程
  18. 用stream流将list集合根据某个字段分组成Map<String,List<T>>类型的集合
  19. 登录接口已修复梦想贩卖机V2 2.0.4 修复版,附带安装教程。
  20. Android 危险权限、权限组列表和所有普通权限

热门文章

  1. socket分块接收_分块WebSocket传输
  2. java 代码分块_Java分块传输的思路
  3. mysql buff cache_Linux中buff/cache内存占用过高解决办法
  4. uniapp 如何获取当前时间,自定义时间格式(根据时间戳转换成时间,判断当前是上午还是下午)
  5. python远程ssh连接linux
  6. Java 发送邮件教程
  7. php伪静态设置,phpstudy伪静态设置
  8. python3爬虫之使用Scrapy框架爬取英雄联盟高清桌面壁纸
  9. selenium 反爬虫之跳过淘宝滑块验证(2020/8)
  10. 光电效应matlab处理图像,用matlab来画表格(实例:处理光电效应及普朗克常数的实验报告)...