对象拷贝类PropertyUtils,BeanUtils,BeanCopier的技术沉淀(2)------缺陷预防

你不知道这些陷阱吧?

陷阱条件

Apache- PropertyUtils

Apache- BeanUtils

Spring-  BeanUtils

Cglib-

BeanCopier

是否可以扩展

useConvete功能

NO

Yes

Yes

Yes,但比较难用

(sourceObject,targetObject)的顺序

逆序

逆序

OK

 

OK

对sourceObject特殊属性的限制:(Date,BigDecimal等)【见备注1】

OK

NO,异常出错

OK

OK

相同属性名,且类型不匹配时候的处理

【见备注2】

异常,拷贝部分属性,非常危险

OK,并能进行初级转换,Long和Integer互转

异常,拷贝部分属性

OK,但是该属性不拷贝

Get和set方法不匹配的处理

【见备注3】

OK

OK

OK

创建拷贝的时候报错,无法拷贝任何属性(当且仅当sourceClass的get方法超过set方法)

 

备注1

对targetObject特殊属性的限制:(Date,BigDecimal等)

原因:dateTimeConveter的conveter没有对null值的处理

public class ErrorBeanUtilObject { //此处省略getter,setter方法

    private String name;

    private java.util.Date date;

}

 public class ErrorBeanUtilsTest {  

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

    ErrorBeanUtilObject from = new ErrorBeanUtilObject(); 

    ErrorBeanUtilObject to = new ErrorBeanUtilObject();  

    //from.setDate(new java.util.Date());

    from.setName("TTTT");

    org.apache.commons.beanutils.BeanUtils.copyProperties(to, from);//如果from.setDate去掉,此处出现conveter异常

    System.out.println(ToStringBuilder.reflectionToString(from));

    System.out.println(ToStringBuilder.reflectionToString(to));

    }  

}

 

备注2

相同属性名,且类型不匹配时候的处理

原因:这两个工具类不支持同名异类型的匹配 !!!【包装类Long和原始数据类型long是可以的】

public class TargetClass {  //此处省略getter,setter方法

    private Long num;  

    private String name;

}

public class TargetClass {  //此处省略getter,setter方法

    private Long num;

    private String name;

}

public class ErrorPropertyUtilsTest {        

    public static void main(String args[]) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException  {  

        SourceClass from = new SourceClass();  

        from.setNum(1);

        from.setName("name"); 

        TargetClass to = new TargetClass();  

        org.apache.commons.beanutils.PropertyUtils.copyProperties(to, from); //抛出参数不匹配异常

        org.springframework.beans.BeanUtils.copyProperties(from, to);

//抛出参数不匹配异常

        System.out.println(ToStringBuilder.reflectionToString(from));    

        System.out.println(ToStringBuilder.reflectionToString(to));  

    }  

}

 

备注3

Get和set方法不匹配的处理

public class ErrorBeanCopierTest {    

    /**

     * 从该用例看出BeanCopier.create的target.class 的每一个get方法必须有队形的set方法

     * @param args

     */

    public static void main(String args[]) {  

        BeanCopier copier = BeanCopier.create(UnSatifisedBeanCopierObject.class, SourceClass.class, false);

        copier = BeanCopier.create(SourceClass.class, UnSatifisedBeanCopierObject.class, false); //此处抛出异常创建 

    }  

}

class UnSatifisedBeanCopierObject {   

    private String name;

    private Long num;

    public String getName() {

       return name;

    }

    public void setName(String name) {

       this.name = name;

    }

    public Long getNum() {

       return num;

    }

//  public void setNum(Long num) {

//     this.num = num;

//  }

}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值