反射创建级联实例对象

一个简单的反射小练习,

package com.example.demo;

import lombok.Data;
import org.apache.commons.lang3.StringUtils;
import org.junit.jupiter.api.Test;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author xiefenghong
 * @date 2022年02月14日 14:50
 * @describe 反射属性赋值
 */
public class ReflectTest {
    @Test
    public void run(){
        Person person = ClassInstanceFactory.createInstance(Person.class, "name:小明|id:1|cloth:{name:大衣|category:{name:羊毛衫}}|sex:male|trousers:{name:裤子}");
        System.out.println(person);
    }
}
/*
 * @Author xiefenghong
 * @Description 实例工厂,用于实例化对象
 * @Date 18:20 2022/2/14
 * @Param
 * @return
 **/
class ClassInstanceFactory{
    private  ClassInstanceFactory(){};
    public static <T>T createInstance(Class<T> obj,String value){
        T instance =null;
        try {
            instance = obj.getDeclaredConstructor().newInstance();
            InstallBeanUtils.installBeanValue(instance,value);
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
        return instance;
    }
}
@Data
class Person{
    private String name;
    private Integer id;
    private Cloth cloth;
    private Trousers trousers;
    private String sex;
}
@Data
class Cloth{
    private String name;
    private Category category;
}
@Data
class Trousers{
    private String name;
    private Category category;
}
@Data
class Category{
    private String name;
}
/**
 * @Author xiefenghong
 * @Description 封装属性工具类
 * @Date 18:20 2022/2/14
 * @Param
 * @return
 **/
class InstallBeanUtils{
    /*
     * @Author xiefenghong
     * @Description 属性封装
     * @Date 18:20 2022/2/14
     * @Param [obj, val]
     * @return void
     **/
    public static void installBeanValue(Object obj,String val) throws NoSuchFieldException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        if (StringUtils.isBlank(val)){
            return;
        }
        if(Objects.isNull(obj)){
            throw new NullPointerException("实例对象为null");
        }
        String valParent=val;
        List<String> list=new ArrayList<>();
        if(valParent.contains("{")){
            list = childrenString(val);
            valParent=transitionString(val);
        }
        Class<?> aClass = obj.getClass();
        String[] valuePairs = valParent.split("\\|");
        AtomicInteger objNum=new AtomicInteger();
        for (String valuePair : valuePairs){
            try {
                String[] values = valuePair.split(":");
                Field field = aClass.getDeclaredField(values[0]);
                if(valuePair.contains("?")){
                    Method method = aClass.getDeclaredMethod(methodNameJoint("get",field));
                    Object childObj = method.invoke(obj);
                    if (Objects.isNull(childObj)){
                        Method setMethod = aClass.getDeclaredMethod(methodNameJoint("set", field), field.getType());
                        setMethod.invoke(obj,field.getType().getConstructor().newInstance());
                        childObj= method.invoke(obj);
                    }
                    try {
                        int num = objNum.get();
                        objNum.incrementAndGet();
                        installBeanValue(childObj,list.get(num).substring(1,list.get(num).length()-1));
                    }catch (Exception e){
                        System.out.println("子类赋值失败");
                    }
                    continue;
                }
                Method method = aClass.getDeclaredMethod(methodNameJoint("set",field), field.getType());
                Object value= methodTypeValue(field, values[1]);
                method.invoke(obj,value);
            }catch (Exception e){
                System.out.println(valuePair+"赋值失败");
            }
        }
    }
    /*
     * @Author xiefenghong
     * @Description 对象类型替换为标记符号
     * @Date 16:28 2022/2/15
     * @Param [val]
     * @return java.lang.String
     **/
    protected static String transitionString(String val){
        return val.replaceAll("\\{.*?\\}{1,}", "?");
    }
    /*
     * @Author xiefenghong
     * @Description 获取对象类型字符集合
     * @Date 16:28 2022/2/15
     * @Param [val]
     * @return java.util.List
     **/
    protected static List childrenString(String val){
        Pattern pattern = Pattern.compile("\\{.*?\\}{1,}");
        Matcher matcher = pattern.matcher(val);
        ArrayList<String> list = new ArrayList<>();
        while (matcher.find()){
            list.add(matcher.group());
        }
        return list;
    }
    /**
     * @Author xiefenghong
     * @Description 属性的值类型转换
     * @Date 18:23 2022/2/14
     * @Param [field, val]
     * @return java.lang.Object
     **/
    protected static Object methodTypeValue(Field field,String val){
        Object obj=null;
        if("java.lang.String".equals(field.getType().getName())){
            return val;
        }else if ("java.lang.Integer".equals(field.getType().getName())){
            obj=Integer.valueOf(val);
        }
        return obj;
    }
    /*
     * @Author xiefenghong
     * @Description 获取get,set方法
     * @Date 18:23 2022/2/14
     * @Param [prefix, field]
     * @return java.lang.String
     **/
    protected static String methodNameJoint(String prefix,Field field){
        String name = field.getName().substring(0, 1).toUpperCase();
        if (field.getName().length()==1){
            return prefix+name;
        }
        return prefix+name+field.getName().substring(1);
    }
}

结果:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值