一.背景
今天在使用BeanUtils.copyProperties()进行对象拷贝的时候遇到了一个坑。因为业务需求,要拷贝一个对象,为了不影响的原有对象的属性,自然不能直接赋值,用set方法又太笨重了,浅克隆和深克隆需要继承接口重写clone()方法,别人的对象,怕改了影响别人。。。于是想到了BeanUtils.copyProperties(),简洁方便。
二.遇坑
一个小坑。。。
Spring包下的org.springframework.beans.BeanUtils.copyProperties();
public static void copyProperties(Object source, Object target) throws BeansException {
copyProperties(source, target, null, (String[]) null);
}
Apeche包下的org.apache.commons.beanutils.BeanUtils.copyProperties();
public static void copyProperties(Object dest, Object orig)
throws IllegalAccessException, InvocationTargetException {
BeanUtilsBean.getInstance().copyProperties(dest, orig);
}
通过源码可以发现,Spring包下的原类在前,目标类在后;而Apeche包下的恰恰相反。
之前用过的Apeche的,这次用Spring的用Apeche的语法写的,结果可想而知。。
三.总结
1.看了下源码和网上讨论,Spring的BeanUtils.copyProperties()会忽略null的属性,只拷贝有值的属性,相比Apache包下的不容易出现一些错误。
2.无论Spring的还是Apache的,cglib包下也有一个对象拷贝工具,Spring和Apache是使用反射机制实现的,cglib是使用动态代理实现的。它们都会牺牲一定的效率。
3.对于只有几个属性的对象,直接使用set,get方法就好,属性多的话尽量使用Spring下的吧。
4.使用工具类在代码简洁等地方上来说是很好的,但是使用之前,无论需求再多、工作代码量再多,都要仔细看看源码实现,避免这些坑。(反思。。)
5.以后自己提炼一下工具类!