Nemo

Nemo 关注TA

路漫漫其修远兮,吾将上下而求索。

Nemo

Nemo

关注TA

路漫漫其修远兮,吾将上下而求索。

  •  普罗旺斯
  • 负责帅就完事了
  • 写了1,493,291字

该文章投稿至Nemo社区   Java  板块 复制链接


JAVA反射操作相关工具

发布于 2017/02/28 19:27 2,602浏览 0回复 8,913


import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 反射相关工具类
 * 
 */
public class ReflectionUtils {

    private static final Logger log = LoggerFactory.getLogger(ReflectionUtils.class);

    /**
     * 获取所有的属性(遍历所有父类)
     *
     * @param clazz
     * @return
     */
    public static Field[] getAllDeclaredFields(Class<?> clazz) {
        return getAllDeclaredFields(clazz, null);
    }

    /**
     * 获取所有的属性(遍历所有父类)
     *
     * @param clazz
     * @return
     */
    public static Map<String, Field> getFieldMap(Class<?> clazz) {
        return getFieldMap(clazz, null);
    }

    /**
     * 获取指定的属性(包括父类),没有则返回空
     *
     * @param clazz
     * @return
     */
    public static Field getField(Class<?> clazz, String fieldName) {
        return getField(clazz, null, fieldName);
    }

    /**
     * 获取所有的属性(遍历所有父类,直到topClazz为止,不包括topClazz中的属性),如果子类、父类中有相同的属性名,则以子类为准
     *
     * @param clazz
     * @return
     */
    public static Field[] getAllDeclaredFields(Class<?> clazz, Class<?> topClazz) {
        Map<String, Field> fieldMap = getFieldMap(clazz, topClazz);
        List<Field> fieldList = new ArrayList<>(fieldMap.size());

        fieldMap.forEach((fieldName, field) -> {
            fieldList.add(field);
        });

        return fieldList.toArray(new Field[fieldList.size()]);
    }

    /**
     * 获取所有的属性(遍历所有父类,直到topClazz为止,不包括topClazz中的属性),如果子类、父类中有相同的属性名,则以子类为准
     *
     * @param clazz
     * @return
     */
    public static Map<String, Field> getFieldMap(Class<?> clazz, Class<?> topClazz) {
        if (topClazz == null) {
            topClazz = Object.class;
        } else if (!topClazz.isAssignableFrom(clazz)) {// 如果clazz不是topClazz的子类
            topClazz = Object.class;
        }
        Class<?> superClazz = clazz;
        List<Class<?>> supperClazzList = new ArrayList<>();
        while (superClazz != null && !topClazz.getName().equals(superClazz.getName())) {
            supperClazzList.add(superClazz);
            superClazz = superClazz.getSuperclass();
        }

        Map<String, Field> fieldMap = new HashMap<>();
        // 如果子类中有与父类同名的属性,则直接覆盖父类的,以子类的为准,所以逆序遍历
        for (int i = supperClazzList.size() - 1; i >= 0; i--) {
            Field[] fields = supperClazzList.get(i).getDeclaredFields();// 获得该类中所有的Field,不包括父类中的
            if (fields == null || fields.length == 0) {
                continue;
            }
            for (Field f : fields) {
                fieldMap.put(f.getName(), f);
            }
        }
        return fieldMap;
    }

    /**
     * 获取指定的属性(包括父类),没有则返回空
     *
     * @param clazz
     * @return
     */
    public static Field getField(Class<?> clazz, Class<?> topClazz, String fieldName) {
        Map<String, Field> fieldMap = getFieldMap(clazz, topClazz);
        return fieldMap.get(fieldName);
    }

    /**
     * 获取属性的get方法
     *
     * @param targetClazz
     * @param fieldName 属性名
     * @return
     */
    public static Method findGetMethod(Class<?> targetClazz, String fieldName) {
        String getMethodName = "get" + StringUtils.capitalize(fieldName);
        return findMethod(targetClazz, getMethodName);
    }

    /**
     * 获取属性的set方法
     *
     * @param targetClazz
     * @param fieldName 属性名
     * @param paramType set方法的参数类型
     * @return
     */
    public static Method findSetMethod(Class<?> targetClazz, String fieldName, Class<?> paramType) {
        String setMethodName = "set" + StringUtils.capitalize(fieldName);
        return findMethod(targetClazz, setMethodName, paramType);

    }

    /**
     * 获取Method
     *
     * @param targetClazz
     * @param methodName 函数名称
     * @param paramTypes 参数类型
     * @return
     */
    public static Method findMethod(Class<?> targetClazz, String methodName, Class<?>... paramTypes) {
        try {
            return targetClazz.getMethod(methodName, paramTypes);
        } catch (NoSuchMethodException | SecurityException e) {
            log.error("", e);
            return null;
        }
    }

    /**
     * 属性的get方法调用
     *
     * @param targetObj 对象示例
     * @param fieldName 属性名
     * @return
     */
    public static Object invokeGetMethod(Object targetObj, String fieldName) {
        Method getMethod = findGetMethod(targetObj.getClass(), fieldName);
        return invokeMethod(targetObj, getMethod);
    }

    /**
     * 属性的set方法调用
     *
     * @param targetObj
     * @param fieldName
     * @param paramValue
     */
    public static void invokeSetMethod(Object targetObj, String fieldName, Object paramValue) {
        Method setMethod = findSetMethod(targetObj.getClass(), fieldName, paramValue.getClass());
        invokeMethod(targetObj, setMethod, paramValue);
    }

    /**
     * 调用指定的方法
     *
     * @param targetObj
     * @param method
     * @param paramValues
     * @return
     */
    public static Object invokeMethod(Object targetObj, Method method, Object... paramValues) {
        try {
            if (method != null) {
                return method.invoke(targetObj, paramValues);
            }
            return null;
        } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
            log.error("", e);
            return null;
        }
    }


    /**
     * 调用指定的方法
     *
     * @param targetObj
     * @param methodName 该方法如果有参数,则不能定义成基本类型,如int应该定义成Integer,否则会报错
     * @param paramValues
     * @return
     */
    public static Object invokeMethod(Object targetObj, String methodName, Object... paramValues) {
        try {
            Class<?>[] paramTypes = null;
            if (paramValues != null && paramValues.length != 0) {
                paramTypes = new Class<?>[paramValues.length];
                for (int i = 0; i < paramValues.length; i++) {
                    paramTypes[i] = paramValues[i].getClass();
                }
            }
            Method method = findMethod(targetObj.getClass(), methodName, paramTypes);
            if (method != null) {
                return method.invoke(targetObj, paramValues);
            }
            return null;
        } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
            log.error("", e);
            return null;
        }
    }

    public static Object getValue(Field field, Object model) {
        try {
            String name = field.getName();
            name = name.substring(0, 1).toUpperCase() + name.substring(1);
            String type = field.getGenericType().toString();
            if (type.equals("class java.lang.String")) {
                Method m = model.getClass().getMethod("get" + name);
                return (String) m.invoke(model);
            }
            if (type.equals("class java.lang.Integer")) {
                Method m = model.getClass().getMethod("get" + name);
                return (Integer) m.invoke(model);
            }
            if (type.equals("class java.lang.Short")) {
                Method m = model.getClass().getMethod("get" + name);
                return (Short) m.invoke(model);
            }
            if (type.equals("class java.lang.Long")) {
                Method m = model.getClass().getMethod("get" + name);
                return (Long) m.invoke(model);
            }
            if (type.equals("class java.lang.Double")) {
                Method m = model.getClass().getMethod("get" + name);
                return (Double) m.invoke(model);
            }
            if (type.equals("class java.lang.Boolean")) {
                Method m = model.getClass().getMethod("get" + name);
                return (Boolean) m.invoke(model);
            }
            if (type.equals("class java.util.Date")) {
                Method m = model.getClass().getMethod("get" + name);
                return (Date) m.invoke(model);
            }
            if (type.equals("class java.math.BigDecimal")) {
                Method m = model.getClass().getMethod("get" + name);
                return (BigDecimal) m.invoke(model);
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return null;
    }

}
点赞(0)

上一个文章:ASCII码对照表 - 记录

下一个文章:List操作工具类

点了个评