通过反射自动级联实例化对象

通过反射级联实例化对象
级联实例化对象,是指对象包含其他对象实例的情况下实例化。要设置被包含对象的属性就得对其实力化。
下面贴上代码。

package reflection;


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

interface IPerson {
    public void act();
}

interface IMessage {
    public void send();
}

class AMessage implements IMessage {
    public String aMessage;

    public AMessage() {
    }

    public String getAMessage() {
        return aMessage;
    }

    public void setAMessage(String aMessage) {
        this.aMessage = aMessage;
    }

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

    @Override
    public void send() {
        System.out.println("这个是A消息");
    }
}

class BMessage implements IMessage {
    public String bMessage;

    public BMessage() {
    }

    public String getBMessage() {
        return bMessage;
    }

    public void setBMessage(String bMessage) {
        this.bMessage = bMessage;
    }

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

    @Override
    public void send() {
        System.out.println("这是B消息");
    }
}

class Student implements IPerson {
    private String name;
    private int age;
    private AMessage aMessage;
    private BMessage bMessage;

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public Student() {
    }

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

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

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

    public AMessage getAMessage() {
        return aMessage;
    }

    public void setAMessage(AMessage aMessage) {
        this.aMessage = aMessage;
    }

    public BMessage getBMessage() {
        return bMessage;
    }

    public void setBMessage(BMessage bMessage) {
        this.bMessage = bMessage;
    }

    @Override
    public String toString() {
        return "姓名:" + name + "、年纪:" + age + "、a信息:" + aMessage + "、b信息:" + bMessage;
    }

    @Override
    public void act() {
        System.out.println("上课");
    }
}

class Player implements IPerson {
    @Override
    public void act() {
        System.out.println("玩游戏");
    }
}

class Factory {
    private Factory() {}
    /**
     * 反射与工厂模式的实现。实现多接口的反射实现
     *
     * @param className 具体的全限定名
     * @param clazz     clazz用来确定泛型以及泛型返回值
     * @param <T>       返回实体类
     * @return
     */
    public static <T> T Factor(String className, Class<T> clazz) {
        T t = null;
        try {
            t = (T) Class.forName(className).newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return t;
    }
    /**
     * 用来对一个类的实现自动配置成员变量,并初始化
     *
     * @param clazz
     * @param value
     * @param <T>
     * @return
     */
    public static <T> T create(Class<T> clazz, String value) {
        //clazz用来确定泛型以及泛型返回值
        try {
            Object object = clazz.getDeclaredConstructor().newInstance();
            BeanUtils.setValue(object, value);
            return (T) object;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

class BeanUtils {//这个类实现类的反射

    private BeanUtils() { }
    public static void setValue(Object obj, String value) {
        String[] results = value.split("\\|");
        for (int i = 0; i < results.length; i++) {
            String[] attval = results[i].split(":");
            try { //这个可以避免错误之后的停止,继续其他的属性反射设置
                if (attval[0].contains(".")) {//表示需要级联更新
                    String[] temp = attval[0].split("\\.");//temp存放冒号前面的拆分。例如:bMessage.bMessage:我是b消息拆分出来就是:1 bMessage 2bMessage
                    Object currentObject = obj;
                    for (int j = 0; j < temp.length - 1; j++) {
                        Method getMethod = currentObject.getClass().getDeclaredMethod("get" +
                                StringUtils.toUppercase(temp[j]));
                        Object tempObject = getMethod.invoke(currentObject); //获取到当前属性是否实例化
                        if (tempObject == null) {
                            Field field = currentObject.getClass().getDeclaredField(temp[j]);//获取属性类型
                            Method method = currentObject.getClass().getDeclaredMethod("set" +
                                    StringUtils.toUppercase(temp[j]), field.getType());
                            Object newObject = field.getType().getDeclaredConstructor().newInstance();
                            method.invoke(currentObject, newObject);//把新的对象实例化
                            currentObject = newObject;
                        } else {
                            currentObject = tempObject;
                        }
                    }
                    //进行属性设置
                    Field field = currentObject.getClass().getDeclaredField(temp[temp.length - 1]);//对当前属性的设置
                    Method method = currentObject.getClass().getDeclaredMethod("set" +
                            StringUtils.toUppercase(temp[temp.length - 1]), field.getType());
                    method.invoke(currentObject, BeanUtils.convertAttributeValue(field.getType().getName(), attval[1]));
                } else {
                    Field field = obj.getClass().getDeclaredField(attval[0]);//取得对应类型,通过类型去获得方法
                    Object val = BeanUtils.convertAttributeValue(field.getType().getName(), attval[1]);
                    obj.getClass().getDeclaredMethod("set" + StringUtils.toUppercase(attval[0]), field.getType()).invoke(obj, val);//此句,获得class-》获取本类的方法-》钩子函数
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 实现属性类型转换
     *
     * @param type  属性类型,通过Field获取
     * @param value 属性类容,传入的都是字符串,需要将其变为指定类型
     * @return 返回转换后的数据
     */
    private static Object convertAttributeValue(String type, String value) {
        if (null == type) {
            return null;
        }
        switch (type) {
            case "java.lang.String":
                return value;
            case "int":
                return Integer.parseInt(value);
            case "double":
                return Double.parseDouble(value);
            case "java.util.Date":
                SimpleDateFormat sdf = null;
                if (value.matches("\\d{4}-\\d{2}-\\d{2}")) {
                    sdf = new SimpleDateFormat("yyyy-MM-dd");
                } else if (value.matches("\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}")) {
                    sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                } else {
                    return new Date();
                }
                try {
                    return sdf.parse(value);
                } catch (ParseException e) {
                    return new Date();
                }
            default:
                return null;
        }
    }
}

class StringUtils {
    private StringUtils() { }
    public static String toUppercase(String value) {//将首字母大写
        if ("".equals(value) || null == value) {
            return value;
        }
        if (value.length() == 1) {
            return value.toUpperCase();
        } else {
            return value.substring(0, 1).toUpperCase() + value.substring(1, value.length());
        }
    }
}

public class ReflectionDemo {
    public static void main(String[] args) throws Exception {
        String value = "name:张三|age:100|aMessage.aMessage:我是a消息|bMessage.bMessage:我是b消息";
        Student student = Factory.create(Student.class, value);
        System.out.println(student);
        System.out.println(student.getAMessage());
        System.out.println(student.getBMessage());

    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值