一.背景
今天在使用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.以後自己提煉一下工具類!