通过java反射初始化对象参数

java反射初始化参数

java反射为各参数赋随机初始值

import org.apache.commons.lang3.StringUtils;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.util.*;

public class Initparam {

    // 初始化的list和array参数的个数
    private static final int arrayNum = 3;

    public static void main(String[] args) throws Exception{
        BizReq<Animal> bizReq = new BizReq<>();
        setAllParameter(bizReq, Animal.class);
        System.out.println(bizReq);
    }

    private static <T> void setAllParameter(BizReq<T> bizReq, Class<T> clazz) throws Exception{
        T t = clazz.getDeclaredConstructor().newInstance();
        if(bizReq.getBody() == null){
            // body为空时要先创建对象
            bizReq.setBody(getInstance(clazz));
        }
        // 设置各参数值
        setParameter(bizReq.getClass(), bizReq);
    }

    /**
     * 给类中的属性赋值
     * @param clazz 要赋值的类
     * @param o 当前类的实体
     * @throws Exception
     */
    private static void setParameter(Class clazz, Object o) throws Exception{
        Field[] declaredFields = clazz.getDeclaredFields();
        for (Field field : declaredFields) {
            field.setAccessible(true);
            Object targetValue = field.get(o);
            /* 若该值已存在值,则不进行赋值*/
            if(targetValue != null && StringUtils.isNotBlank(targetValue.toString())){
                // 若该值为非自定义类型对象,则跳过,否则进行赋值(递归调用)
                Class targetClass = targetValue.getClass();
                if(isCommonClass(targetValue)){
                    continue;
                }
                setParameter(targetClass, targetValue);
            }
            // 对该属性进行赋值
            setNotBlankValue(clazz, field.getName(), o, null);
        }
        return;
    }

    /**
     * 对属性进行赋值
     * @param clazz 要赋值的字段类型
     * @param name 要赋值的字段名
     * @param o 要赋值的字段实体
     * @param defaultValue 要进行赋的值
     * @throws Exception
     */
    private static void setNotBlankValue(Class clazz, String name, Object o, Object defaultValue)
            throws Exception{
        String setMethod = "set" + name.substring(0, 1).toUpperCase() + name.substring(1);
        Field declaredField = clazz.getDeclaredField(name);
        // 属性的类型
        Class<?> type = declaredField.getType();
        // 如果是object类型,则直接跳过
        if(type.isAssignableFrom(Object.class)){
            return;
        }
        Object instanceValue = getInstance(type);
        Method method = clazz.getMethod(setMethod, type);
        // 若存在defaultValue,则赋值defaultValue
        if(defaultValue != null){
            method.invoke(o, defaultValue);
            setSuperClassValue(clazz.getSuperclass(), o);
            return;
        }
        // 非自定义类型并且非list,则直接使用instanceValue赋值
        if(isCommonClass(instanceValue) && (!(instanceValue instanceof List))){
            method.invoke(o, instanceValue);
            setSuperClassValue(clazz.getSuperclass(), o);
            return;
        }
        // 处理list类型的值
        if (instanceValue instanceof List) {
            // 当前集合的泛型类型
            Type genericType = declaredField.getGenericType();
            if (null == genericType) {
                throw new Exception("未获取到list的泛型类型");
            }
            if (genericType instanceof ParameterizedType) {
                ParameterizedType pt = (ParameterizedType) genericType;
                // 得到泛型里的class类型对象
                Class<?> actualTypeArgument = (Class<?>) pt.getActualTypeArguments()[0];
                Object actualType = getInstance(actualTypeArgument);
                //....actualType字段处理
                method.invoke(o, set2list(actualType));
            }
            setSuperClassValue(clazz.getSuperclass(), o);
            return;
        }
        // 如果以上常见类型都没有匹配上,则代表需要匹配自定义类型
        if(true){
            Field[] fields = type.getDeclaredFields();
            Object childObject = getInstance(type);
            for (Field field : fields) {
                field.setAccessible(true);
                Object targetValue = field.get(childObject);
                if(targetValue != null && StringUtils.isNotBlank(targetValue.toString())){
                    // 若该值为非自定义类型对象,则跳过,否则进行赋值(递归调用)
                    if(isCommonClass(targetValue)){
                        continue;
                    }
                    setParameter(targetValue.getClass(), targetValue);
                }
                // 给对象内部属性赋值
                setNotBlankValue(type, field.getName(), childObject, null);
                setSuperClassValue(clazz.getSuperclass(), o);
            }
            // 对该对象整体赋值
            setNotBlankValue(clazz, name, o, childObject);
        }
    }

    /**
     * 对list全量赋值
     * @param t list中包含的对象
     * @param <T>
     * @return
     * @throws Exception
     */
    private static <T> List<T> set2list(T t) throws Exception{
        List<T> list = new ArrayList<>();
        if(isCommonClass(t) && (!(t instanceof List))){
            for (int i = 0; i < arrayNum; i++) {
                list.add((T)getInstance(t.getClass()));
            }
            return list;
        }
        // 获取泛型内的各字段类型
        Class<?> clazz = t.getClass();
        Field[] field = clazz.getDeclaredFields();
        // 插入三个值
        for (int i = 0; i < arrayNum; i++) {
            for (int j = 0; j < field.length; j++) {
                String fieldName = field[j].getName();
                setNotBlankValue(clazz, fieldName, t, null);
            }
            list.add(t);
        }
        return list;
    }

    /**
     * 为父类赋值
     * @param clazz 父类
     * @param o 实体
     * @throws Exception
     */
    private static void setSuperClassValue(Class clazz, Object o) throws Exception{
        if(clazz != null){
            setParameter(clazz, o);
        }
    }

    /**
     * 获取实例化值
     * 和isCommonClass方法对应
     * @param clazz 要实例化的类
     * @param <T> 实例化的值
     * @return
     * @throws Exception
     */
    private static <T> T getInstance(Class<T> clazz) throws Exception{
        // 父类isAssignableFrom子类,所以此处的判断作为相等判断
        if(clazz.isAssignableFrom(Object.class)){
            return (T) new Object();
        }
        // 之所以用isAssignableFrom是因为一些class并没有无参构造
        if(clazz.isAssignableFrom(String.class)){
            return (T) UUID.randomUUID().toString();
        }
        if(clazz.isAssignableFrom(int.class)){
            return (T) (Integer)(new Random().nextInt(200000));
        }
        if(clazz.isAssignableFrom(Integer.class)){
            return (T) (Integer)(new Random().nextInt(200000));
        }
        if(clazz.isAssignableFrom(Date.class)){
            return (T) new Date();
        }
        if(clazz.isAssignableFrom(boolean.class)){
            return (T) (Boolean)true;
        }
        if(clazz.isAssignableFrom(Boolean.class)){
            return (T) (Boolean)true;
        }
        if(clazz.isAssignableFrom(Double.class)){
            return (T) (Double.valueOf(new Random().nextDouble()));
        }
        if(clazz.isAssignableFrom(Float.class)){
            return (T) (Float.valueOf(new Random().nextFloat()));
        }
        if(clazz.isAssignableFrom(double.class)){
            return (T) (Double.valueOf(new Random().nextDouble()));
        }
        if(clazz.isAssignableFrom(Long.class)){
            return (T) (Long.valueOf(new Random().nextLong()));
        }
        if(clazz.isAssignableFrom(long.class)){
            return (T) (Long.valueOf(new Random().nextLong()));
        }
        if(clazz.isAssignableFrom(float.class)){
            return (T) (Float.valueOf(new Random().nextFloat()));
        }
        if(clazz.isAssignableFrom(BigDecimal.class)){
            return (T) new BigDecimal(String.valueOf(new Random().nextInt(200000)));
        }
        if(clazz.isAssignableFrom(List.class)){
            return (T) new ArrayList<>();
        }
        if(clazz.isAssignableFrom(String[].class)){
            String[] strs = new String[arrayNum];
            for (int i = 0; i < arrayNum; i++) {
                strs[i] = UUID.randomUUID().toString();
            }
            return (T) strs;
        }
        Object o = null;
        try {
            o = clazz.getDeclaredConstructor().newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return (T) o;
    }

    /**
     * 判断该实体是否是日常类(即非自定义对象类)
     * 和getInstance方法对应
     */
    private static boolean isCommonClass(Object o) throws Exception{
        // 父类isAssignableFrom子类
        if(o.getClass().isAssignableFrom(Object.class)){
            return true;
        }
        // 子类instanceof父类
        if(o instanceof String || o instanceof String[] || o instanceof Integer || o instanceof Date || o instanceof Boolean
            || o instanceof Double || o instanceof Float || o instanceof Long || o instanceof BigDecimal || o instanceof List){
            return true;
        }
        return false;
    }
}
上一篇:Spring 中优雅的获取泛型信息


下一篇:你知道的反射是这样吗?(二)