關(guān)于兩個BeanUtils.copyProperties()的用法及區(qū)別
兩個BeanUtils.copyProperties()用法及區(qū)別
這兩個類在不同的包下面,而這兩個類的copyProperties()方法里面?zhèn)鬟f的參數(shù)賦值是相反的。
例如:
a,b為對象
BeanUtils.copyProperties(a, b);
public static void copyProperties(Object source, Object target) throws BeansException {//source 源文件,target 目標(biāo)文件
? ? ? ? copyProperties(source, target, (Class)null, (String[])null);
? ? }BeanUtils是org.apache.commons.beanutils.BeanUtils,b拷貝到a
?public static void copyProperties(Object dest, Object orig) throws IllegalAccessException, InvocationTargetException {//destination,目標(biāo)文件,original原始的,源文件
? ? ? ? BeanUtilsBean.getInstance().copyProperties(dest, orig);
? ? }這兩個不要搞混了!
使用Beanutils.copyProperties()遇到的問題
BeanUtils.copyProperties VS PropertyUtils.copyProperties
兩者最大的區(qū)別是:
BeanUtils.copyProperties會進(jìn)行類型轉(zhuǎn)換,而PropertyUtils.copyProperties不會。
既然進(jìn)行了類型轉(zhuǎn)換,那BeanUtils.copyProperties的速度比不上PropertyUtils.copyProperties。
因此,PropertyUtils.copyProperties應(yīng)用的范圍稍為窄一點(diǎn),它只對名字和類型都一樣的屬性進(jìn)行copy,如果名字一樣但類型不一樣,它會報錯
使用BeanUtils有幾個要注意的地方:
1.對于類型為Boolean/Short/Integer/Float/Double的屬性,它會轉(zhuǎn)換為0:
public class User {
private Integer intVal;
private Double doubleVal;
private Short shortVal;
private Long longVal;
private Float floatVal;
private Byte byteVal;
private Boolean booleanVal;
}
User src = new User();
User dest = new User();
BeanUtils.copyProperties(dest, src);
System.out.println(src);
System.out.println(dest);
//輸出
User [intVal=null, doubleVal=null, shortVal=null, longVal=null, floatVal=null, byteVal=null, booleanVal=null]
User [intVal=0, doubleVal=0.0, shortVal=0, longVal=0, floatVal=0.0, byteVal=0, booleanVal=false] 在stackoverflow上有人解釋說是因為這幾個類型都有對應(yīng)的基本類型,在進(jìn)行類型轉(zhuǎn)換時,有可能遇到類似Integer -> int的轉(zhuǎn)換,此時顯然不能對int類型的屬性賦值為null,因此統(tǒng)一轉(zhuǎn)換為0。
如何讓它不要轉(zhuǎn)為0呢?可以這樣:
import org.apache.commons.beanutils.converters.IntegerConverter; ? IntegerConverter converter = new IntegerConverter(null); //默認(rèn)為null,而不是0? BeanUtilsBean beanUtilsBean = new BeanUtilsBean();? beanUtilsBean.getConvertUtils().register(converter, Integer.class);?
2.對于java.util.Date/BigDecimal/java.sql.Date/java.sql.Timestamp/java.sql.Time這幾個類,如果值為null,則在copy時會拋異常,需要使用對應(yīng)的Conveter:
public class User2 {
private java.util.Date javaUtilDateVal;
private java.sql.Date javaSqlDateVal;
private java.sql.Timestamp javaSqlTimeStampVal;
private BigDecimal bigDecimalVal;
private java.sql.Time javaSqlTime;
}
User2 src = new User2();
User2 dest = new User2();
BeanUtilsBean beanUtilsBean = new BeanUtilsBean();
//如果沒有下面幾行,則在轉(zhuǎn)換null時會拋異常,例如:org.apache.commons.beanutils.ConversionException: No value specified for 'BigDecimal'
//在org.apache.commons.beanutils.converters這個包下面有很多的Converter,可以按需要使用
beanUtilsBean.getConvertUtils().register(new org.apache.commons.beanutils.converters.BigDecimalConverter(null), BigDecimal.class);
beanUtilsBean.getConvertUtils().register(new org.apache.commons.beanutils.converters.DateConverter(null), java.util.Date.class);
beanUtilsBean.getConvertUtils().register(new org.apache.commons.beanutils.converters.SqlTimestampConverter(null), java.sql.Timestamp.class);
beanUtilsBean.getConvertUtils().register(new org.apache.commons.beanutils.converters.SqlDateConverter(null), java.sql.Date.class);
beanUtilsBean.getConvertUtils().register(new org.apache.commons.beanutils.converters.SqlTimeConverter(null), java.sql.Time.class);
beanUtilsBean.copyProperties(dest, src);
System.out.println(src);
System.out.println(dest);
使用BeanUtils還會經(jīng)常碰到這樣變態(tài)的需求:
- 假設(shè)是從A復(fù)制到B:
- 需求1:如果B中某字段有值(不為null),則該字段不復(fù)制;也就是B中該字段沒值時,才進(jìn)行復(fù)制,適合于對B進(jìn)行補(bǔ)充值的情況。
- 需求2:如果A中某字段沒值(為null),則該字段不復(fù)制,也就是不要把null復(fù)制到B當(dāng)中。
- 對于需求1,可以這樣:
import org.apache.commons.beanutils.BeanUtilsBean;
import org.apache.commons.beanutils.PropertyUtils;
public class CopyWhenNullBeanUtilsBean extends BeanUtilsBean{
@Override
public void copyProperty(Object bean, String name, Object value)
throws IllegalAccessException, InvocationTargetException {
try {
Object destValue = PropertyUtils.getSimpleProperty(bean, name);
if (destValue == null) {
super.copyProperty(bean, name, value);
}
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
}
}
}
對于需求2,可以這樣:
import org.apache.commons.beanutils.BeanUtilsBean;
public class CopyFromNotNullBeanUtilsBean extends BeanUtilsBean {
@Override
public void copyProperty(Object bean, String name, Object value) throws IllegalAccessException, InvocationTargetException {
if (value == null) {
return;
}
super.copyProperty(bean, name, value);
}
}
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Springmvc國際化自動配置代碼實(shí)現(xiàn)
這篇文章主要介紹了Springmvc國際化自動配置代碼實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-04-04
SpringBoot Security密碼加鹽實(shí)例
這篇文章主要為打擊介紹了SpringBoot Security密碼加鹽實(shí)例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-02-02
Springboot-dubbo-fescar 阿里分布式事務(wù)的實(shí)現(xiàn)方法
這篇文章主要介紹了Springboot-dubbo-fescar 阿里分布式事務(wù)的實(shí)現(xiàn)方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2019-03-03
SpringBoot?全局線程池配置及應(yīng)用小結(jié)
為了提高應(yīng)用程序的性能和響應(yīng)速度,線程池是一個非常重要的工具,本文主要介紹了Spring?Boot?全局線程池配置及應(yīng)用,具有一定的參考價值,感興趣的可以了解一下2024-05-05

