(反射与简单Java类)级联对象实例化

级联对象实例化

上一节设置多种数据类型

如果现在给定的类对象之中存在有其他的引用的级联关系的情况下,称为多级设置。

例如一个雇员属于一个部门,一个部门属于一个公司,所以这个时候对于简单Java类的基本关系定义如下:(setter、getter略)

class Company{

    private String  name;
    private Date createDate;


}


class Dept{

    private String name;
    private String loc;
    private Company  company;

}

class Emp {

    private String eName;
    private String job;
    private double salary;
    private long empno;
    private Dept dept;

}

如果要通过Emp进行操作,则应该使用“.”作为级联关系处理:

dept.dname:财务部Emp类实例化对象.getDept().setDname("财务部")
dept.company.name:腾讯Emp类实例化对象.getDept().getCompany.setName("腾讯")

考虑到代码的简介性,应该考虑可以通过级联的配置自动实现类中属性的实例化。现在的属性存在有多级的关系,那么对于多级的关系就必须与单级的配置区分开。

package reflect;

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

public class Demo{

    public static void main(String[] args) throws Exception{

       String value = "eName:Smith|job:Clerk|salary:8912.12|empno:1"+"|dept.name:财务部|dept.company.name:腾讯";
       Emp emp = ClassInstanceFactory.create(Emp.class,value);
       System.out.println("雇员编号:"+emp.getEmpno()+"、姓名:"+emp.getEName()+"、职位:"+ emp.getJob()+"、薪资:"+emp.getSalary()
       +"、部门:"+emp.getDept().getName()+"、公司:"+emp.getDept().getCompany().getName());

    }

}


class ClassInstanceFactory{

    private ClassInstanceFactory(){}

    /**
     * 实例化对象的创建方法,该对象可以根据传入的字符串结构“属性:内容|属性:内容”传入
     * @param clazz 要进行反射实例化Class类对象,有Class就可以反射实例化对象
     * @param value 要给对象的属性内容
     * @return   一个配置好属性内容的java类对象
     */
    public static <T>T create(Class<?> clazz,String value) {

        //如果要采用反射进行简单Java类对象属性设置的时候,类中必须要有无参构造
        try {
            Object obj =  clazz.getDeclaredConstructor().newInstance();
            BeanUtils.setValue(obj,value);  //调用BeanUtil实现属性的更改
            return (T)obj;  //返回对象
        } catch (Exception e) {
            e.printStackTrace();    //如果此时出现了错误,抛出异常也没有作用
            return null;
        }


    }

}

class StringUtils{  //实现首字母大写

    public static String initcap(String str){

        if (str == null || "".equals(str)){
            return str;
        }
        if(str.length() == 1){
            return str.toUpperCase();
        }else{
            return str.substring(0,1).toUpperCase() + str.substring(1);
        }

    }

}

class BeanUtils{    //进行Bean处理的类

    private BeanUtils(){}

    /**
     * 实现指定对象的属性设置
     * @param obj   要进行反射操作的实例化对象
     * @param value 包含有指定内容的字符窜,格式为"属性:内容|属性:内容"
     */
    public static void setValue(Object obj,String value){

        String[] result = value.split("\\|");   //按照“|”进行每一组属性的拆分
        for(int x = 0;x < result.length;x++){   //循环设置属性内容
            //attval[0]保存的是属性名称,attval[1]保存的是内容
            String[] attval = result[x].split(":");   //获取“属性名称”与“内容”\
            try{
                if(attval[0].contains(".")){    //多级配置
                    String[] temp  = attval[0].split("\\.");
                    Object currentObject = obj;
                    //最后一位肯定是类中属性名称,所以不再本次实例化处理的范畴之内
                    for(int i = 0; i <temp.length -1;i++ ){ //实例化对象
                        //调用相应的getter方法,如果getter方法返回了null表示该对象未实例化
                        Method getMethod = currentObject.getClass().getMethod("get"+StringUtils.initcap(temp[i]));
                        Object tempObject = getMethod.invoke(currentObject);    //调用geter方法
                        if(tempObject == null){  //该对象并没有实例化
                            Field filed = currentObject.getClass().getDeclaredField(temp[i]);   //获取属性类型
                            //获取set对象的方法
                            Method method = currentObject.getClass().getDeclaredMethod("set"
                                                    +StringUtils.initcap(temp[i]),filed.getType());
                            //调用setter方法并调用,填入实例化对象
                            Object NewObject = filed.getType().getDeclaredConstructor().newInstance();
                            method.invoke(currentObject,NewObject);
                            currentObject = NewObject;
                        }else{
                            currentObject = tempObject;
                        }
                    }
                    //进行属性内容的设置
                    Field filed = currentObject.getClass().getDeclaredField(temp[temp.length-1]); //获取成员
                    //获取set方法
                    Method setMethod = currentObject.getClass().getMethod("set"+StringUtils.initcap(temp[temp.length-1]),filed.getType());
                    //进行数据的转型
                    Object val = BeanUtils.convertAttributeValue(filed.getType().getName(),attval[1]);
                    setMethod.invoke(currentObject,val);    //调用setter方法进行赋值
                }else{  //单级配置
                    Field filed = obj.getClass().getDeclaredField(attval[0]); //获取成员
                    //根据取名规范set+首字母大写属性获取方法
                    Method setMethod = obj.getClass().getMethod("set"+StringUtils.initcap(attval[0]),filed.getType());
                    //进行数据的转型
                    Object val = BeanUtils.convertAttributeValue(filed.getType().getName(),attval[1]);
                    setMethod.invoke(obj,val);    //调用setter方法进行赋值
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }

    }

    /**
     * 实现属性 类型转换处理
     * @param type  属性类型,通过Filed获取的
     * @param value 属性的内容,传入的都是字符串,需要将其变为指定类型
     * @return  转换后的数据
     */
    private static Object convertAttributeValue(String type,String value){

        if("long".equals(type) || "java.lang.Long".equals(type)){
            return Long.parseLong(value);
        }else if("int".equals(type) || "java.lang.Integer".equals(type)){
            return Integer.parseInt(value);
        }else if("double".equals(type) || "java.lang.Double".equals(type)){
            return Double.parseDouble(value);
        }else if("java.util.Date".equals(type)){
            SimpleDateFormat simpleDateFormat = null;
            if(value.matches("\\d{4}-\\d{2}-\\d{2}")){  //日期类型
                simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
            }else if(value.matches("\\d{4}-\\d{2}-\\d{2}:\\d{2}:\\d{2}:\\d{2}")){
                return simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            }else{
                return new Date();  //当前日期
            }
            try {
                return simpleDateFormat.parse(value);
            } catch (ParseException e) {
                return new Date();
            }
        }else{  //字符串
            return value;
        }

    }

}

class Company{

    private String  name;
    private Date createDate;

    public String getName() {
        return name;
    }

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

    public Date getCreateDate() {
        return createDate;
    }

    public void setCreateDate(Date createDate) {
        this.createDate = createDate;
    }
}


class Dept{

    private String name;
    private String loc;
    private Company  company;

    public String getName() {
        return name;
    }

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

    public String getLoc() {
        return loc;
    }

    public void setLoc(String loc) {
        this.loc = loc;
    }

    public Company getCompany() {
        return company;
    }

    public void setCompany(Company company) {
        this.company = company;
    }



}

class Emp {

    private String eName;
    private String job;
    private double salary;
    private long empno;
    private Dept dept;

    public double getSalary() {
        return salary;
    }

    public void setSalary(double salary) {
        this.salary = salary;
    }

    public long getEmpno() {
        return empno;
    }

    public void setEmpno(long empno) {
        this.empno = empno;
    }

    public String getEName() {
        return eName;
    }

    public void setEName(String eName) {
        this.eName = eName;
    }

    public String getJob() {
        return job;
    }

    public void setJob(String job) {
        this.job = job;
    }

    public String geteName() {
        return eName;
    }

    public void seteName(String eName) {
        this.eName = eName;
    }

    public Dept getDept() {
        return dept;
    }

    public void setDept(Dept dept) {
        this.dept = dept;
    }
}

雇员编号:1、姓名:Smith、职位:Clerk、薪资:8912.12、部门:财务部、公司:腾讯

在以后的开发之中简单Java类的复制处理将不再重复调用setter操作完成,而这种处理是在正规开发中普遍采用的方式。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值