【Java笔记(20)】反射与简单Java类之实现多种属性自动赋值以及级联赋值

一、核心代码

    /**
     * 給实例的属性赋值
     *
     * @param instance 对象实例
     * @param values   参数类型
     * @return void
     * @Author Xlu
     * @Date 20:10 2020-06-14
     */
public static void autoValue(Object instance , String values) {
        String[] result = values.split("\\|");
        for (int i = 0 ; i < result.length ; i++) {
            Object currentObj=instance;
            Object currentObjBefore=instance;
            String[] attVal = result[i].split(":");
            //但一个属性出现错误的时候,后面的属性照常赋值
            try {
                //判断属性名称里面是否有点,如果有点的话就应该是联级
                if (attVal[0].contains(".")) {
                    String temp[] = attVal[0].split("\\.");
                    //最后一个该赋值了
                    for (int o = 0 ; o < temp.length -1; o++) {
                        Field field = currentObj.getClass().getDeclaredField (temp[o]);
                        Method getMethod = currentObj.getClass().getDeclaredMethod("get" + StringUtilAutoValue.attrib(temp[o]));
                        Method setMethod = currentObj.getClass().getDeclaredMethod("set" + StringUtilAutoValue.attrib(temp[o]),field.getType());

                        //判断该属性未实例化
                        if (getMethod.invoke(currentObj) == null) {
                            //创建一个实例
                            currentObj = field.getType().getDeclaredConstructor().newInstance();
                            setMethod.invoke(currentObjBefore , currentObj);
                            currentObjBefore=currentObj;
                        }else{
                            currentObj=getMethod.invoke(currentObj);
                        }
                    }

                    //获取成员,这里是为了要获取属性的类型
                    Field field = currentObj.getClass().getDeclaredField(temp[temp.length-1]);
                    System.out.println(field);
                    Method method = currentObj.getClass().getDeclaredMethod("set" + StringUtilAutoValue.attrib(temp[temp.length-1]) , field.getType());
                    System.out.println(method);
                    Object attributeValue = BeanUtilAutoValue.convertAttributeValue(field.getType().getName() , attVal[1]);
                    //调用方法
                    method.invoke(currentObj , attributeValue);
                }else{
                    //获取成员,这里是为了要获取属性的类型
                    Field field = currentObj.getClass().getDeclaredField(attVal[0]);
                    //根据方法名称去找方法的话一定要给一个参数,不然会找到多个重载的函数。
                    Method method = currentObj.getClass().getDeclaredMethod("set" + StringUtilAutoValue.attrib(attVal[0]) , field.getType());
                    Object attributeValue = BeanUtilAutoValue.convertAttributeValue(field.getType().getName() , attVal[1]);
                    //调用方法
                    method.invoke(currentObj , attributeValue);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
    }

二、完整代码

package reflect.andjavaclass;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * 属性自动赋值
 * <br>
 * 获取方法:    public Method getDeclaredMethod(String name, Class<?>... parameterTypes)
 * <br>
 * 获取属性:    public Field getDeclaredField(String name)
 * <br>
 * 获取属性类型(Field):    public Class<?> getType()
 * <br>
 * 调用方法(Method):    public Object invoke(Object obj, Object... args)
 * <br>
 *
 * @ClassName: AttribAutoValue
 * @Author: Xlu
 * @Date: 2020-06-14 18:54
 * @Version 11
 **/
public class AttribAutoValue {
    public static void main(String[] args) {
        String values = "name:张三|age:28|property:20000.209020|sex:男|birthday:1999-09-19|home.room.size:100平分|home.address:潮汕";
        PersonAutoValue person = (PersonAutoValue) ClassInstanceFactoryAutoValue.getInstance(PersonAutoValue.class , values);
        System.out.println(person.toString());
    }
}


/**
 * 获取实例的工厂类,实现自动赋值
 *
 * @Author Xlu
 * @Date 2020-06-14 19:01
 * @ClassName AttribAutoValue
 * @Version 11
 **/
class ClassInstanceFactoryAutoValue {

    private ClassInstanceFactoryAutoValue() {

    }

    /**
     * @param clazz  Class实例
     * @param values 多个参数
     * @return T
     * @Author Xlu
     * @Date 19:54 2020-06-14
     */
    public static <T> T getInstance(Class<T> clazz , String values) {
        try {
            T t = (T) clazz.getDeclaredConstructor().newInstance();
            BeanUtilAutoValue.autoValue(t , values);
            return t;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}


/**
 * 字符串操作类
 *
 * @Author Xlu
 * @Date 2020-06-14 19:13
 * @ClassName AttribAutoValue
 * @Version 11
 **/
class StringUtilAutoValue {

    /**
     * @return 返回一个首字母大写的字符串
     * @Author Xlu
     * @Date 19:11 2020-06-14
     * @Param value 字符串
     */
    public static String attrib(String value) {
        if (value == null || "".equals(value)) {
            return value;
        } else if (value.length() == 1) {
            return value.toUpperCase();
        } else {
            return value.substring(0 , 1).toUpperCase() + value.substring(1);
        }
    }
}

/**
 * 自动赋值的工具类
 *
 * @Author Xlu
 * @Date 2020-06-14 19:09
 * @ClassName BeanUtilAutoValue
 * @Version 11
 **/
class BeanUtilAutoValue {
    /**
     * 給实例的属性赋值
     *
     * @param instance 对象实例
     * @param values   参数类型
     * @return void
     * @Author Xlu
     * @Date 20:10 2020-06-14
     */
    public static void autoValue(Object instance , String values) {
        String[] result = values.split("\\|");
        for (int i = 0 ; i < result.length ; i++) {
            Object currentObj=instance;
            Object currentObjBefore=instance;
            String[] attVal = result[i].split(":");
            //但一个属性出现错误的时候,后面的属性照常赋值
            try {
                //判断属性名称里面是否有点,如果有点的话就应该是联级
                if (attVal[0].contains(".")) {
                    String temp[] = attVal[0].split("\\.");
                    //最后一个该赋值了
                    for (int o = 0 ; o < temp.length -1; o++) {
                        Field field = currentObj.getClass().getDeclaredField (temp[o]);
                        Method getMethod = currentObj.getClass().getDeclaredMethod("get" + StringUtilAutoValue.attrib(temp[o]));
                        Method setMethod = currentObj.getClass().getDeclaredMethod("set" + StringUtilAutoValue.attrib(temp[o]),field.getType());

                        //判断该属性未实例化
                        if (getMethod.invoke(currentObj) == null) {
                            //创建一个实例
                            currentObj = field.getType().getDeclaredConstructor().newInstance();
                            setMethod.invoke(currentObjBefore , currentObj);
                            currentObjBefore=currentObj;
                        }else{
                            currentObj=getMethod.invoke(currentObj);
                        }
                    }

                    //获取成员,这里是为了要获取属性的类型
                    Field field = currentObj.getClass().getDeclaredField(temp[temp.length-1]);
                    System.out.println(field);
                    Method method = currentObj.getClass().getDeclaredMethod("set" + StringUtilAutoValue.attrib(temp[temp.length-1]) , field.getType());
                    System.out.println(method);
                    Object attributeValue = BeanUtilAutoValue.convertAttributeValue(field.getType().getName() , attVal[1]);
                    //调用方法
                    method.invoke(currentObj , attributeValue);
                }else{
                    //获取成员,这里是为了要获取属性的类型
                    Field field = currentObj.getClass().getDeclaredField(attVal[0]);
                    //根据方法名称去找方法的话一定要给一个参数,不然会找到多个重载的函数。
                    Method method = currentObj.getClass().getDeclaredMethod("set" + StringUtilAutoValue.attrib(attVal[0]) , field.getType());
                    Object attributeValue = BeanUtilAutoValue.convertAttributeValue(field.getType().getName() , attVal[1]);
                    //调用方法
                    method.invoke(currentObj , attributeValue);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
    }

    /**
     * 根据类中的属性更改传入属性的类型
     *
     * @param attType 属性的类型
     * @param value   属性的值
     * @return java.lang.Object
     * @Author Xlu
     * @Date 20:13 2020-06-14
     */
    public static Object convertAttributeValue(String attType , String value) {

        if ("double".equals(attType) || "java.lang.Double".equals(attType)) {
            return Double.parseDouble(value);
        } else if ("int".equals(attType) || "java.lang.Integer".equals(attType)) {
            return Integer.parseInt(value);
        } else if ("java.util.Date".equals(attType)) {
            SimpleDateFormat time;
            if (value.matches("\\d{4}-\\d{2}-\\d{2}")) {
                time = new SimpleDateFormat("yyyy-MM-dd");
            } else if (value.matches("\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}")) {
                time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            } else {
                return new Date();
            }
            try {
                return time.parse(value);
            } catch (ParseException e) {
                e.printStackTrace();
                return new Date();
            }

        } else {
            return value;
        }
    }
}


/**
 * 为了方便,所有属性用String类型
 *
 * @Author Xlu
 * @Date 2020-06-14 19:03
 * @ClassName PersonAutoValue
 * @Version 11
 **/
class PersonAutoValue {
    private String name;
    private int age;
    private String sex;
    private double property;
    private Date birthday;
    private HomeAutoValue home;

    public HomeAutoValue getHome() {
        return home;
    }

    @Override
    public String toString() {
        return "PersonAutoValue{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", sex='" + sex + '\'' +
                ", property=" + property +
                ", birthday=" + birthday +
                ", home=" + home +
                '}';
    }
    public void setHome(HomeAutoValue home) {
        this.home = home;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public double getProperty() {
        return property;
    }

    public void setProperty(double property) {
        this.property = property;
    }

    public PersonAutoValue() {

    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    public int getAge() {
        return age;
    }
}


class RoomAutoValue {
    private String size;

    public RoomAutoValue() {

    }

    public String getSize() {
        return size;
    }

    public void setSize(String size) {
        this.size = size;
    }

    @Override
    public String toString() {
        return "RoomAutoValue{" +
                "size='" + size + '\'' +
                '}';
    }
}

class HomeAutoValue {
    private String address;
    private RoomAutoValue room;

    @Override
    public String toString() {
        return "HomeAutoValue{" +
                "address='" + address + '\'' +
                ", room=" + room +
                '}';
    }

    public RoomAutoValue getRoom() {
        return room;
    }

    public void setRoom(RoomAutoValue room) {
        this.room = room;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public HomeAutoValue() {

    }
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

「已注销」

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值