反射与简单Java类

1、传统开发过程中,简单Java类中如果有大量的属性,那么就会存在大量的setter与getter方法,从而导致代码编写的重复性会非常高。要想解决对象的重复处理操作就可以利用反射机制。

2、属性自动设置解决方案

import java.lang.reflect.* ;
public class BDemo {
    public static void main(String[] args) throws Exception {
        String value = "ename:Bob|job:Boss" ;
        Emp emp = ClassInstanceFactory.creat(Emp.class, value) ;
        System.out.println("姓名:" + emp.getEname() + ";职位:" + emp.getJob()) ;
    }
}
class ClassInstanceFactory {
    private ClassInstanceFactory() {}
    /**
    *实例化对象的创建方法
    *@param clazz 要进行反射实例化的Class类对象,即有Class就可以反射实例化对象
    *@param value 要设置给对象属性的属性值
    *@return 一个已经配置好属性内容的Java类对象
    */
    public static <T> T creat(Class<T> clazz, String value) {
        //使用反射进行简单Java类对象属性设置的时候,类中必须要有无参构造
        try{
            Object obj = clazz.getDeclaredConstructor().newInstance() ;
            BeanUtils.setValue(obj,value) ; //通过反射设置属性
            return (T)obj ;
        }catch(Exception e) {
            e.printStackTrace() ;
            return null ;
        }//如果此处不进行异常处理,那么在属性设置错误时程序会停止执行,进行处理后如果属性设置错误就返回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) ;
        }
    }
}
//进行Bean处理的类
class BeanUtils {
    private BeanUtils() {}
    /**
    *实现指定对象的属性设置
    *@param obj 要进行反射操作的实例化对象
    *@param value 包含指定内容的字符串,格式:例:ename:Bob|job:Boss
    *@return 一个已经配置好属性内容的Java类对象
    */
    public static void setValue(Object obj, String value) {
        String results [] = value.split("\\|") ;
        for(int x = 0 ; x < results.length ; x ++) {
            String attribute [] = results[x].split(":") ;
            try {
                Field field = obj.getClass().getDeclaredField(attribute[0]) ; //获取成员
                Method setMethod = obj.getClass().getDeclaredMethod("set"+StringUtils.initcap(attribute[0]),field.getType()) ;
                setMethod.invoke(obj,attribute[1]) ; //调用setter方法设置内容
            }catch(Exception e) {
                e.printStackTrace() ;
            }
        }
    }
}
class Emp {
    private String ename ;
    private String job ;
    public void setEname(String ename) {
        this.ename = ename ;
    }
    public String getEname() {
        return this.ename ;
    }
    public void setJob(String job) {
        this.job = job ;
    }
    public String getJob() {
        return this.job ;
    }
}

【重要】3、级联对象实例化与级联属性赋值

import java.lang.reflect.* ;
import java.text.ParseException ;
import java.text.SimpleDateFormat ;
import java.util.Date ;
public class BDemo {
    public static void main(String[] args) throws Exception {
        String value = "empo:1314|ename:Bob|job:Boss|date:1998-03-04|" + "dept.dname:技术部|dept.company.name:www";
        Emp emp = ClassInstanceFactory.creat(Emp.class, value) ;
        System.out.println("编号:" + emp.getEmpo() + ";姓名:" + emp.getEname() + ";职位:" + emp.getJob() + ";入职日期:" + emp.getDate() + ";公司:" + emp.getDept().getCompany().getName() + ";部门:" + emp.getDept().getDname() ) ;
    }
}
class ClassInstanceFactory {
    private ClassInstanceFactory() {}
    /**
    *实例化对象的创建方法
    *@param clazz 要进行反射实例化的Class类对象,即有Class就可以反射实例化对象
    *@param value 要设置给对象属性的属性值
    *@return 一个已经配置好属性内容的Java类对象
    */
    public static <T> T creat(Class<T> clazz, String value) {
        //使用反射进行简单Java类对象属性设置的时候,类中必须要有无参构造
        try{
            Object obj = clazz.getDeclaredConstructor().newInstance() ;
            BeanUtils.setValue(obj,value) ; //通过反射设置属性
            return (T)obj ;
        }catch(Exception e) {
            e.printStackTrace() ;
            return null ;
        }//如果此处不进行异常处理,那么在属性设置错误时程序会停止执行,进行处理后如果属性设置错误就返回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) ;
        }
    }
}
//进行Bean处理的类
class BeanUtils {
    private BeanUtils() {}
    /**
    *实现指定对象的属性设置
    *@param obj 要进行反射操作的实例化对象
    *@param value 包含指定内容的字符串,格式:例:ename:Bob|job:Boss
    *@return 一个已经配置好属性内容的Java类对象
    */
    public static void setValue(Object obj, String value) {
        String results [] = value.split("\\|") ;
        for(int x = 0 ; x < results.length ; x ++) {
            String attribute [] = results[x].split(":") ;
            try {
                if(attribute[0].contains(".")) { //多级配置
                    String temp [] = attribute[0].split("\\.") ;
                    //进行实例化,最后一位是指定类中的属性名不用实例化
                    Object currentObject = obj ;
                    for(int y = 0 ; y < temp.length - 1 ; y ++) {
                        Method getMethod = currentObject.getClass().getDeclaredMethod("get" + StringUtils.initcap(temp[y])) ;
                        Object tempObject = getMethod.invoke(currentObject) ; //转型
                        if(tempObject == null) { //对象未被实例化
                            Field field = currentObject.getClass().getDeclaredField(temp[y]) ;
                            Method method = currentObject.getClass().getDeclaredMethod("set" + StringUtils.initcap(temp[y]),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 setMethod = currentObject.getClass().getDeclaredMethod("set" + StringUtils.initcap(temp[temp.length - 1]),field.getType()) ;
                    Object val = BeanUtils.convertAttributeValue(field.getType().getName(),attribute[1]) ;
                    setMethod.invoke(currentObject,val) ;    
                } else {
                    Field field = obj.getClass().getDeclaredField(attribute[0]) ; //获取成员
                    Method setMethod = obj.getClass().getDeclaredMethod("set"+StringUtils.initcap(attribute[0]),field.getType()) ;
                    Object val = BeanUtils.convertAttributeValue(field.getType().getName(),attribute[1]) ;
                    setMethod.invoke(obj,val) ; //调用setter方法设置内容            
                }
            }catch(Exception e) {
                e.printStackTrace() ;
            }
        }
    }
    /**
    *实现属性类型转换
    *@param Type 属性类型,通过Field获取的
    *@param value 属性的内容,传入的都是字符串,需要将其变为指定类型
    *@return 转婚后的数据
    */
    //因为invoke()方法中参数value是Object类型
    public 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.int".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 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) {
                e.printStackTrace() ;
                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 dname ;
    private String loc ;
    private Company company ;
    public String getDname() {
        return dname;
    }
    public void setDname(String dname) {
        this.dname = dname;
    }
    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 long empo ;
    private Date date ;
    private Dept dept ;
    public void setEname(String ename) {
        this.ename = ename ;
    }
    public String getEname() {
        return this.ename ;
    }
    public void setJob(String job) {
        this.job = job ;
    }
    public String getJob() {
        return this.job ;
    }
    public void setEmpo(long empo) {
        this.empo = empo ;
    }
    public long getEmpo() {
        return this.empo ;
    }
    public void setDate(Date date) {
        this.date = date ;
    }
    public Date getDate() {
        return this.date ;
    }
    public Dept getDept() {
        return dept;
    }
    public void setDept(Dept dept) {
        this.dept = dept;
    }
}

运行结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值