反射工具类:释放资源、获取对对象属性、设置属性等

反射工具类:释放资源、获取对对象属性、设置属性等

package cn.elwy.common.util;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Map;

import org.apache.commons.beanutils.BeanUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cn.elwy.common.exception.RunException;

/**
 * 反射工具类
 * @author huangsq
 * @version 2.0, 2013-09-09
 * @since 1.0, 2012-02-19
 */
@SuppressWarnings("unchecked")
public final class ReflectUtil {

    private static final Logger logger = LoggerFactory.getLogger(ReflectUtil.class);

    public static final String SPLIT_DOT = "\\.";
    public static final String SPLIT_COLON = ":";
    public static final String SPLIT_VIRGULE = "\\|";
    public static final String DOT = ".";
    public static final String DOT_SPLIT = "\\.";
    public static final String GET = "get";
    public static final String SET = "set";
    public static final String IS = "is";
    public static final String PARENTHESIS = "()";

    private ReflectUtil() {
    }

    /**
     * 关闭资源
     * @param object 要关闭的对象
     */
    public static void close(Object object) {
        try {
            invoke(object, "close");
        } catch (Exception e) {
            logger.warn(e.getMessage(), e);
        }
    }

    /**
     * 释放资源
     * @param object 要释放的对象
     */
    public static void dispose(Object object) {
        try {
            invoke(object, "dispose");
        } catch (Exception e) {
            logger.warn(e.getMessage(), e);
        }
    }

    /**
     * 执行指定对象的方法,方法必需无参数,不抛出错误
     * @param object 执行的对象
     * @param methodName 方法名称
     * @return
     */
    public static <T> T run(Object object, String methodName) {
        T result = null;
        try {
            result = invoke(object, methodName);
        } catch (Exception e) {
            logger.debug(e.getMessage(), e);
        }
        return result;
    }

    /**
     * 执行指定对象的方法,不抛出错误,目标参数类型根据参数决定
     * @param object 被执行对象
     * @param methodName 方法名称
     * @param args 目标方法的参数,参数可以为null
     * @return
     */
    public static <T> T run(Object object, String methodName, Object[] args) {
        T result = null;
        try {
            result = invoke(object, methodName, args);
        } catch (Exception e) {
            logger.warn(e.getMessage(), e);
        }
        return result;
    }

    /**
     * 执行指定对象的方法,不抛出错误
     * @param object 被执行对象
     * @param methodName 方法名称
     * @param args 目标方法的参数
     * @param argsType 参数类型
     * @return
     */
    public static <T> T run(Object object, String methodName, Object[] args, Class<?>[] argsType) {
        T result = null;
        try {
            result = invoke(object, methodName, args, argsType);
        } catch (Exception e) {
            logger.warn(e.getMessage(), e);
        }
        return result;
    }

    /**
     * 根据属性名称获取属性的值,可以是私有属性或父类的属性
     * @param object 被执行对象
     * @param fieldName 属性名称
     * @return
     */
    public static <T> T getFieldValue(Object object, String fieldName) {
        try {
            Field field = getField(object.getClass(), fieldName);
            return (T) field.get(object);
        } catch (Exception e) {
            throw new RunException(e.getMessage(), e);
        }
    }

    /**
     * 执行指定对象的方法,方法必需无参数,获取返回值
     * @param object 被执行对象
     * @param methodNames 方法名称(不带括号),多个方法用“.”分割
     * @return
     */
    public static <T> T getMethodValue(Object object, String methodName) {
        try {
            return invoke(object, methodName);
        } catch (Exception e) {
            throw new RunException(e.getMessage(), e);
        }
    }

    /**
     * 执行指定对象的方法,方法必需无参数,获取返回值
     * @param object 被执行对象
     * @param methodNames 方法名称,多个方法用“.”分割
     * @return
     */
    public static <T> T getTableColumnValue(Object object, String methodNames, boolean isSupportMap) {
        String[] methods = methodNames.split(SPLIT_DOT);
        for (String method : methods) {
            if (object == null) {
                return null;
            }
            if (method.endsWith(PARENTHESIS)) {
                method = method.replace(PARENTHESIS, "");
                object = run(object, method);
            } else if (isSupportMap && object instanceof Map) {
                object = ((Map<?, ?>) object).get(method);
            } else {
                try {
                    object = getFieldValue(object, method);
                } catch (Exception e) {
                    logger.warn(e.getMessage(), e);
                    return null;
                }
            }
        }
        return (T) object;
    }

    /**
     * 获取对象的值,当isSupportMap=true且对象是一个map时,使用method作为key获取map中的值。
     * 否则利用反射机制执行指定对象的方法,方法必需无参数,获取返回值
     * @param object 被执行对象
     * @param methodNames 方法名称,多个对象用“|”分割,格式:UserInfo:getOrg().address.name|Org:name
     * @param isSupportMap 支持方法名作为map的key取值
     * @return
     */
    public static <T> T getTreeColumnValue(Object object, String methodNames, boolean isSupportMap) {
        String[] classNames = methodNames.split(SPLIT_VIRGULE);
        String name = object.getClass().getSimpleName();
        String[] propertyName = null;
        for (String className : classNames) {
            propertyName = className.split(SPLIT_COLON);
            if (propertyName.length == 1) {
                return getTableColumnValue(object, propertyName[0], isSupportMap);
            } else if (name.equals(propertyName[0])) {
                return getTableColumnValue(object, propertyName[1], isSupportMap);
            }
        }
        return getTableColumnValue(object, propertyName[1], isSupportMap);
    }

    /**
     * 根据属性名称设置属性的值,可以是私有属性或父类的属性
     * @param object 被执行对象
     * @param fieldName 属性名称
     * @param value 设置的值
     */
    public static void setFieldValue(Object object, String fieldName, Object value) {
        try {
            Field field = getField(object.getClass(), fieldName);
            field.set(object, value);
        } catch (Exception e) {
            throw new RunException(e.getMessage(), e);
        }
    }

    /**
     * 根据属性名称设置属性的值,可以是私有属性或父类的属性
     * @param object 被执行对象
     * @param fieldName 属性名称
     * @param value 设置的值
     */
    public static void setProperty(Object object, String fieldName, Object value) {
        try {
            BeanUtils.setProperty(object, fieldName, value);
        } catch (Exception e) {
            throw new RunException(e.getMessage(), e);
        }
    }

    /**
     * 设置对象的值,利用反射机制执行指定对象的方法,将参数值设置给对象
     * @param object 被执行对象
     * @param methodName 方法名称
     * @param value 参数的值,参数类型根据值决定
     */
    public static void setMethodValue(Object object, String methodName, Object value, Class<?> argsType,
            boolean isSupportMap) {
        if (isSupportMap && object instanceof Map) {
            ((Map<String, Object>) object).put(methodName, value);
        } else {
            invoke(object, methodName, new Object[] { value }, new Class<?>[] { argsType });
        }
    }

    /**
     * 根据属性名称设置属性的值,可以是私有属性或父类的属性
     * @param object 被执行对象
     * @param methodNames 属性名称或"方法名.属性名称"
     * @param value 设置的值
     */
    public static void setTableColumnValue(Object object, String methodNames, Object value, boolean isSupportMap) {
        String[] methods = methodNames.split(SPLIT_DOT);
        int length = methods.length - 1;
        for (int i = 0; i <= length; i++) {
            if (object == null) {
                return;
            }
            String method = methods[i];
            if (i == length) {
                if (method.endsWith(PARENTHESIS)) {
                    method = method.replace(PARENTHESIS, "");
                    if (method.startsWith(GET)) {
                        method = method.replaceFirst(GET, "");
                    } else if (method.startsWith(IS)) {
                        method = method.replaceFirst(IS, "");
                    }
                } else if (isSupportMap && object instanceof Map) {
                    ((Map<String, Object>) object).put(method, value);
                }
                setProperty(object, method, value);
            } else {
                object = getTableColumnValue(object, method, isSupportMap);
            }
        }
    }

    /**
     * 根据属性名称设置属性的值,可以是私有属性或父类的属性
     * @param object 被执行对象
     * @param methodNames 属性名称或"方法名.属性名称"
     * @param value 设置的值
     */
    public static void setTreeColumnValue(Object object, String methodNames, Object value, boolean isSupportMap) {
        String[] classNames = methodNames.split(SPLIT_VIRGULE);
        String name = object.getClass().getSimpleName();
        String[] propertyName = null;
        for (String className : classNames) {
            propertyName = className.split(SPLIT_COLON);
            if (propertyName.length == 1) {
                setTableColumnValue(object, propertyName[0], value, isSupportMap);
                return;
            } else if (name.equals(propertyName[0])) {
                setTableColumnValue(object, propertyName[1], value, isSupportMap);
                return;
            }
        }
        setTableColumnValue(object, propertyName[1], value, isSupportMap);
    }

    /**
     * 执行指定对象的方法,方法必需无参数
     * @param object 被执行对象
     * @param methodName 方法名称
     * @return
     * @throws Exception
     */
    public static <T> T invoke(Object object, String methodName) {
        if (object == null) {
            return null;
        }
        try {
            Method method = getMethod(object.getClass(), methodName);
            return (T) method.invoke(object);
        } catch (Exception e) {
            throw new RunException(e.getMessage(), e);
        }
    }

    /**
     * 执行指定对象的方法,参数与参数类型不匹配,需要调用:
     * invoke(Object object, String methodName, Object[] args, Class<?>[] argTypes)方法
     * @param object 被执行对象
     * @param methodName 方法名称
     * @param args 目标方法的参数
     * @return
     * @throws Exception
     */
    public static <T> T invoke(Object object, String methodName, Object[] args) {
        if (args == null || args.length == 0) {
            return invoke(object, methodName);
        }
        Class<?>[] argTypes = new Class<?>[args.length];
        for (int i = 0; i < args.length; i++) {
            argTypes[i] = args[i].getClass();
        }
        return invoke(object, methodName, args, argTypes);
    }

    /**
     * 执行指定对象的方法
     * @param object 被执行对象
     * @param methodName 方法名称
     * @param args 目标方法的参数
     * @param argTypes 参数类型
     * @return
     * @throws Exception
     */
    public static <T> T invoke(Object object, String methodName, Object[] args, Class<?>[] argTypes) {
        if (object == null) {
            return null;
        }
        try {
            Method method = getMethod(object.getClass(), methodName, argTypes);
            return (T) method.invoke(object, args);
        } catch (Exception e) {
            throw new RunException(e.getMessage(), e);
        }
    }

    private static Field getField(Class<?> clazz, String fieldName) throws NoSuchFieldException {
        Field field = null;
        try {
            field = clazz.getField(fieldName);
        } catch (NoSuchFieldException e) {
            try {
                field = clazz.getDeclaredField(fieldName);
            } catch (NoSuchFieldException ex) {
                if (clazz.getSuperclass() == null) {
                    return field;
                } else {
                    return getField(clazz.getSuperclass(), fieldName);
                }
            }
        }
        // 调用private属性的关键一句话
        field.setAccessible(true);
        return field;
    }

    /**
     * 利用递归找一个类的指定方法,如果找不到,去父亲里面找直到最上层Object对象为止。
     * @param clazz 目标类
     * @param methodName 方法名
     * @param argsType 方法参数类型
     * @return 对象的方法
     * @throws NoSuchMethodException
     */
    private static Method getMethod(Class<?> clazz, String methodName, final Class<?>... argsType)
            throws NoSuchMethodException {
        Method method = null;
        try {
            method = clazz.getMethod(methodName, argsType);
        } catch (NoSuchMethodException e) {
            try {
                method = clazz.getDeclaredMethod(methodName, argsType);
            } catch (NoSuchMethodException ex) {
                if (clazz.getSuperclass() == null) {
                    return method;
                } else {
                    return getMethod(clazz.getSuperclass(), methodName, argsType);
                }
            }
        }
        // 调用private方法的关键一句话
        method.setAccessible(true);
        return method;
    }

}


转载于:https://www.cnblogs.com/huangshiqiang/p/4057941.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值