将对象的属性值复制到另一个对象中

本文介绍了一种自定义方法,用于将一个对象的属性值复制到另一个对象中,特别适用于属性名不同的情况。同时,对比了Spring框架下BeanUtils类的copyProperties方法,展示了其在属性复制上的灵活性和效率。

将对象的属性值复制到另一个对象中

/***
 * 将第一个对象的属性值复制到第二个对象中
 * @param <T> 第一个对象
 * @param <R> 第二个对象
 */
class HandleObject<T,R>{

    //保存指定不同的字段名称和数据类型
    private List<Attribute> attributes;

    /**
     * 存放两个对象的字段和字段类型
     */
    private class Attribute {
        private String fieldOne;
        private String fieldTwo;
        private Class<?> type;

        Attribute(){
        }
        Attribute(String fieldOne, String fieldTwo, Class<?> type){
            this.fieldOne = fieldOne;
            this.fieldTwo = fieldTwo;
            this.type = type;
        }
    }

    /**
     * 初始化不指定大小
     */
    HandleObject(){
        this.attributes = new ArrayList<>();
    }
    /**
     * 初始化时指定大小
     * @param size
     */
    HandleObject(Integer size){
        this.attributes = new ArrayList<>(size);
    }

    /***
     * 指定对象的字段
     * @param fieldOne 第一个对象的字段
     * @param fieldTwo 第二个对象的字段
     * @param type 第二个字段的数据类型
     */
    public void add(String fieldOne,String fieldTwo,Class<?> type){
        this.attributes.add(new Attribute(fieldOne,fieldTwo,type));
    }

    /***
     * 对象属性值赋值
     * @param data 第一个对象
     * @param noData 第二个对象
     * @return 第二个对象
     * @throws Exception
     */
    public R serviceWrite(T data, Class<R> noData) throws Exception {
        return this.serviceWrite(data,noData,this.attributes);
    }

    /**
     * 对象属性值赋值
     * @param data 第一个对象
     * @param noData 第二个对象
     * @param list 指定字段
     * @return 第二个对象
     * @throws Exception
     */
    private R serviceWrite(T data, Class<R> noData, List<Attribute> list) throws Exception {
        //获取操作类反射对象
        Class<?> cls = data.getClass();
        Class<?> claData = Class.forName(noData.getName());

        //获取实例
        Object newInstance = claData.newInstance();

        //获取所有属性名称
        Field[] fields = cls.getDeclaredFields();
        Field[] declaredFields = claData.getDeclaredFields();

        //循环赋值(属性和类型相同情况)
        for (Field field : fields) {
            for (Field fieldLess : declaredFields) {
                //属性名称
                String name = field.getName();
                //属性类型
                String type = field.getType().getName();
                //禁止安全检查,可以提高性能
                field.setAccessible(true);
                //取出需要赋值进去的对象属性和类型

                String lessName = fieldLess.getName();
                String lessType = fieldLess.getType().getName();
                //判断属性名和类型都相同就赋值
                if (name.equals(lessName) && type.equals(lessType)){
                    //赋值
                    Method setMet = claData.getDeclaredMethod("set" + initcap(lessName), lessType.getClass()) ;
                    //从data对象中取出值赋值到noData
                    setMet.invoke(newInstance,field.get(data));
                }
                //判断是否为非属性赋值
            }
        }
        //循环遍历指定的字段赋值
        if (list.size() > 0 && null != list){
            list.forEach(action ->{
                try {
                    //根据属性名取出属性值
                    Method getMethod = cls.getDeclaredMethod("get" + initcap(action.fieldOne));
                    //赋值
                    Method setMethod = claData.getDeclaredMethod("set" + initcap(action.fieldTwo), action.type);
                    setMethod.invoke(newInstance,getMethod.invoke(data));
                }catch (Exception e){
                    new RuntimeException("赋值错误" + e.getMessage());
                }
            });
        }
        return (R) newInstance;
    }

    /***
     * 首字母大写操作
     * @param str 转大写的字符串
     * @return
     */
    public static String initcap(String str) {
        return str.substring(0, 1).toUpperCase() + str.substring(1) ;
    }
}
  • 创建第一个类
public class Book {
    private String name ;
    private String title ;
    private Integer price ;

   //get and set 方法略
}
  • 创建第二个类
public class School{
    private String name ;
    private String className;
    private Integer classCount ;

   //get and set 方法略
}
  • 创建测试方法
public static void main(String[] args) {

        try {
            Book book = new Book();
            book.setName("领域驱动模型设计");
            book.setTitle("复杂也业务设计");
            book.setPrice(589);

            /***
             * 将Book对象的数据复制到School中
             * 并指定属性名(如果不指定属性名,对象的属性名不同的地方就不能复制过去)
             */
            HandleObject<Book, School> attribute = new HandleObject<>(2);
            attribute.add("title", "className", String.class);
            attribute.add("price", "classCount", Integer.class);

            School school = attribute.serviceWrite(book, School.class);
            System.out.println("name:" + school.getName() + "className:" + school.getClassName() + "count:" + school.getClassCount());
            //打印结果:name:领域驱动模型设计className:复杂也业务设计count:589
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

使用Spring中BeanUtils方法实现

Book book = new Book();
book.setName("领域驱动模型设计");
book.setTitle("复杂也业务设计");
book.setPrice(589);

School school = new School();

//赋值所有相同的字段
BeanUtils.copyProperties(book,school);

//忽略掉 不需要赋值的字段(name)
BeanUtils.copyProperties(book,school,null,"name");
System.out.println("name:" + school.getName() + "className:" + school.getClassName() + "count:" + school.getClassCount());

BeanUtils所在类

org.springframework.beans.BeanUtils;

转载请指明……

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值