工具类篇3——反射工具类(方法反射)

子目录

《工具类篇3——反射工具类(方法反射)》
《工具类篇3——反射工具类(对象反射)》
《工具类篇3——反射工具类(获取泛型类型)》


工具类全都是阿里代码规范与SonalLint扫描通过的,可以放心使用!

本工具包的公网Maven引用地址如下

<dependency>
    <groupId>com.gitee.taotaojs</groupId>
    <artifactId>comn-basic</artifactId>
    <version>1.0.0</version>
</dependency>

直接引用即可。
之后我也会出一个关于上传公网的踩坑手册,以及发布一下我用的CheckStyle文件检查相关异味,敬请期待!

【附上仓库地址】
阿里云的Maven仓库
sonatype仓库


注意事项:
本工具类有使用到同包下的工具类,详情请看gitee的代码,有所有工具类的代码~

import com.taotaojs.exception.MyInnerException; - 内部异常类,直接继承RuntimeException

主要功能

  • 方法名称操作【MethodUtil】
    • 根据属性名称获取get/set/表列名字符串
  • 方法反射工具类【ReflectUtil】
    • 获取get/set/普通方法对象
    • 直接运行get/set/普通方法对象
    • 批量执行集合内所有对象的某个方法
    • 批量对于私用属性解锁/加锁操作
    • 获取类类型中所有属性列表

具体代码

方法名操作工具类
package com.gitee.taotaojs.util.reflect;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author TaoTaojs
 * @date 2019/4/24 16:51
 * <p>Description</p>
 * 将属性名转换为get/set方法名
 * 关联类:
 */
public final class MethodUtil {
    /** 魔法值提取 */
    private static final String SET_PREFIX = "set";
    /** 魔法值提取 */
    private static final String GET_PREFIX = "get";
    /** 正则初始化 */
    private static Pattern humpPattern = Pattern.compile("[A-Z]");

    private MethodUtil(){}

    /**
     * 首字母变成大写
     * @param name 属性名
     * @return 字符串
     */
    private static String capitalize(String name) {
        if (name == null || name.length() == 0) {
            return name;
        }
        return name.substring(0, 1).toUpperCase() + name.substring(1);
    }

    /**
     * 获取set方法名
     * @param propertyName 属性名
     * @return 字符串
     */
    protected static String setMethodName(String propertyName) {
        return SET_PREFIX + capitalize(propertyName);
    }

    /**
     * 获取get方法名
     * @param propertyName 属性名
     * @return 字符串
     */
    protected static String getMethodName(String propertyName) {
        return GET_PREFIX + capitalize(propertyName);
    }

    /**
     * 根据属性名称获取表列名称
     * @param propertyName 属性名
     * @return 字符串
     */
    public static String getColnumName(String propertyName){
        Matcher matcher = humpPattern.matcher(propertyName);
        StringBuffer sb = new StringBuffer();
        while (matcher.find()) {
            matcher.appendReplacement(sb, "_" + matcher.group(0).toLowerCase());
        }
        matcher.appendTail(sb);
        return sb.toString();
    }

}
方法反射工具类
package com.gitee.taotaojs.util.reflect;

import com.gitee.taotaojs.exception.MyInnerException;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

/**
 * 反射工具类
 *
 * @author TaoTaojs
 * @author TaoTaojs
 * @date 2020/7/2 4:24 PM
 * <p>Description</p>
 * 直接获取反射方法对象
 * 运行反射方法对象与批量运行
 * 属性名加锁
 * 关联类:
 * 参考链接:
 * History: <br/>
 * <author>        <time>                      <version>          <desc>
 * TaoTaojs        2020/7/2 4:24 PM                V1.0           支持获取反射方法对象并直接运行,批量运行某方法,属性名加锁
 */

public final class ReflectUtil {

    private ReflectUtil(){}

    /**
     * 获取该类型的get方法对象
     * @param clazz 对象类类型
     * @param fieldName 属性名称
     * @param <T> 对象泛型
     * @return 属性对象
     */
    public static<T> Method getGetMethod(Class<T> clazz, String fieldName){
        return getMethod(clazz, MethodUtil.getMethodName(fieldName));
    }

    /**
     * 获取该类型的get方法对象
     * @param clazz 对象类类型
     * @param fieldName 属性名称
     * @param classes 方法传参
     * @param <T> 对象泛型
     * @return 实现对象
     */
    public static<T> Method getSetMethod(Class<T> clazz, String fieldName, Class classes){
        return getMethod(clazz, MethodUtil.setMethodName(fieldName), classes);
    }

    /**
     * 直接创建方法对象
     * @param clazz 对象类类型
     * @param methodName 方法名称
     * @param classes 方法传参
     * @param <T> 对象泛型
     * @return 方法对象
     */
    public static<T> Method getMethod(Class<T> clazz, String methodName, Class... classes){
        try {
            return clazz.getMethod(methodName, classes);
        } catch (NoSuchMethodException e) {
            throw new MyInnerException(e);
        }
    }

    /**
     * 使用方法名称直接执行方法
     * @param obj 对象实例
     * @param methodName 方法名称
     * @param classes 方法传参
     * @param objs 传参变长数组
     * @param <T> 对象泛型
     * @return 执行的返回值
     */
    public static<T> T invokeMethod(T obj, String methodName, Class[] classes, T[] objs){
        Method method = getMethod(obj.getClass(), methodName, classes);
        return invokeMethod(obj, method, objs);
    }

    /**
     * 直接运行无参方法
     * @param obj 对象实例
     * @param methodName 方法名称
     * @param <T> 对象泛型
     * @return 方法对象
     */
    public static<T> T invokeMethod(T obj, String methodName){
        return invokeMethod(obj, methodName, null, null);
    }
    @SuppressWarnings("checkstyle:MissingJavadocMethod")
    public static<T, V> T invokeMethod(T obj, Method method, V... objs){
        try {
            return (T) method.invoke(obj, objs);
        } catch (Exception e) {
            throw new MyInnerException(e);
        }
    }
    @SuppressWarnings("checkstyle:MissingJavadocMethod")
    public static<T> T invokeGet(T obj, Field field){
        try {
            return (T) field.get(obj);
        } catch (IllegalAccessException e) {
            throw new MyInnerException(e);
        }
    }
    @SuppressWarnings("checkstyle:MissingJavadocMethod")
    public static void invokeSet(Object obj, Field field, Object objs){
        try {
            field.set(obj, objs);
        } catch (IllegalAccessException e) {
            throw new MyInnerException(e);
        }
    }

    @SuppressWarnings("checkstyle:MissingJavadocMethod")
    public static<T> T invokeGet(T obj, String fieldName){
        return invokeMethod(obj, getGetMethod(obj.getClass(), fieldName));
    }
    @SuppressWarnings("checkstyle:MissingJavadocMethod")
    public static<T, V> T invokeSet(T obj, String fieldName, V object){
        return invokeMethod(obj, getSetMethod(obj.getClass(), fieldName, object.getClass()), object);
    }
    /** set的属性类型是面向接口时使用,例:setData(Map),object的类型假设是linkedHashMap,如果不传clazz,将会找不到setData(linkedHashMap)这个方法 */
    @SuppressWarnings("checkstyle:MissingJavadocMethod")
    public static<T, V> T invokeSet(T obj, String fieldName, V object, Class<V> clazz){
        return invokeMethod(obj, getSetMethod(obj.getClass(), fieldName, clazz), object);
    }

    /**
     * 批量执行集合内所有对象的某个方法
     * @param clazz 对象类类型
     * @param objList 对象集合
     * @param methodName 方法名称
     * @param classes 传参类型
     * @param objs 传参
     * @param <T> 对象泛型
     * @return 原来的集合
     */
    public static<T> List<T> invokeMethodList(Class<T> clazz, List<T> objList, String methodName, Class[] classes, Object[] objs){
        List<T> list = new ArrayList<>();
        Method method = getMethod(clazz, methodName, classes);
        for (Object o : objList) {
            invokeMethod(o, method, objs);
        }
        return list;
    }
    @SuppressWarnings("checkstyle:MissingJavadocMethod")
    public static<T> void invokeMethodList(List<T> list, Method method, Object[] objs){
        for (Object o : list) {
            invokeMethod(o, method, objs);
        }
    }

    /**
     * 批量解锁/加锁属性字段
     * @param flag true加锁
     * @param fields 属性对象变长参数
     */
    public static void fieldAccess(boolean flag, Field... fields){
        for (Field field : fields) {
            field.setAccessible(flag);
        }
    }


    /**
     * 获取类类型中所有属性列表
     * @param clazz 类类型
     * @return 属性列表
     */
    public static PropertyDescriptor[] getPropertyList(Class<?> clazz){
        BeanInfo beanInfo = null;
        try {
            beanInfo = Introspector.getBeanInfo(clazz);
        } catch (IntrospectionException e) {
            throw new MyInnerException(e);
        }
        return beanInfo.getPropertyDescriptors();
    }


}

PS:

文章链接

《工具类篇1——POI工具类》——待更新
《工具类篇2——集合工具类》
《工具类篇3——反射工具类》(共三篇)
《工具类篇4——大数字工具类》(共三篇)——待更新
《工具类篇5——时间戳工具类》(共两篇)——待更新
《工具类篇6——字符串工具类》——待更新
《工具类篇7——线程池工具类》——待更新
《…》

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值