一、引言
常用的拷贝方式:
- 手动get&set实现。
- 通过Cglib的BeanCopier实现。
- 通过Apache的BeanUtils实现。
- 通过Apache的PropertyUtils实现。
- 通过Spring的BeanUtils实现。
(此模块先对常用拷贝方式进行总结,后文会详细介绍深拷贝&浅拷贝的区别以及实现方式。)
二.常用拷贝方式之间的区别
1. 手动get&set实现:
简单,粗暴,高性能
2. 通过Cglib的BeanCopier实现(使用动态代理,效率高):
不使用类型转换器:
BeanCopier beanCopier = BeanCopier.create(SourceClass.class, TargetClass.class, false); 前赋后
beanCopier.copy(sourceClass, targetClass, null);
不支持不同类型字段的转换,但可通过自己实现的converter转换器实现类型之间的转换。
使用类型转换器:
BeanCopier beanCopier = BeanCopier.create(SourceClass.class, TargetClass.class, true); 前赋后
beanCopier.copy(sourceClass, targetClass, converter); //converter为自己实现的转换器。
例如:
public class Long2StringConvert implements Converter {
@Override
public Object convert(Object sourceValue, Class targetClass, Object methodName) {
if( null != sourceValue && sourceValue.getClass().equals(Long.class) && targetClass.equals(String.class)) {
return String.valueOf(sourceValue);
}
return sourceValue;
}
}
生成用于复制两个类的BeanCoper类:
public final static BeanCopier dir2DirVOCopier = BeanCopier.create(Dir.class,DirVO.class,true);
执行拷贝:
BeanCopyProvider.dir2DirVOCopier.copy(dir, vo, new Long2StringConvert());
参考文档:
CGLIB中BeanCopier源码实现 - 简书 // CGLIB中BeanCopier源码实现
对象拷贝类PropertyUtils,BeanUtils,BeanCopier的技术沉淀(1)------功能简介_express_wind的专栏-优快云博客
对象拷贝类PropertyUtils,BeanUtils,BeanCopier的技术沉淀(2)------缺陷预防_express_wind的专栏-优快云博客
对象拷贝类PropertyUtils,BeanUtils,BeanCopier的技术沉淀(3)------优化方案_express_wind的专栏-优快云博客_beancopier和beanutils
3. 通过Apache的BeanUtils实现(反射机制):
使用:BeanUtils.copyProperties(targetClass, sourceClass); 后赋前
提供自动转换功能,即发现两个JavaBean的同名属性为不同类型时,在支持的数据类型范围内进行转换。
BeanUtils支持的转换类型如下:
* java.lang.BigDecimal
* java.lang.BigInteger
* boolean and java.lang.Boolean
* byte and java.lang.Byte
* char and java.lang.Character
* java.lang.Class
* double and java.lang.Double
* float and java.lang.Float
* int and java.lang.Integer
* long and java.lang.Long
* short and java.lang.Short
* java.lang.String
* java.sql.Date
* java.sql.Time
* java.sql.Timestamp
这里要注意一点,java.util.Date是不被支持的,而它的子类java.sql.Date是被支持的。因此如果对象包含时间类型的属性,且注意被转换的时候,一定要使用java.sql.Date类型。否则在转换时会提示argument mistype异常。
可使用转换器beanutils.Converter,增强apache的beanUtils的拷贝属性,注册一些新的类型转换。
例:
ConvertUtils.register(new DateConvert(), java.util.Date.class);
4. 通过Apache的PropertyUtils实现(反射机制):
使用:PropertyUtils.copyProperties(targetClass, sourceClass); 后赋前
不提供自动转换功能。当类型不一致时会抛出异常。

本文详细介绍了Java中对象拷贝的各种方式,包括手动get&set、Cglib的BeanCopier、Apache的BeanUtils、PropertyUtils以及Spring的BeanUtils。对比了它们之间的性能和区别,指出Cglib BeanCopier在性能上表现优秀。此外,文章讨论了浅拷贝和深拷贝的概念,解释了默认赋值操作为浅拷贝,并提供了实现深拷贝的两种方法:实现Cloneable接口和使用序列化。通过代码示例展示了这两种深拷贝的实现方式。
最低0.47元/天 解锁文章
1017

被折叠的 条评论
为什么被折叠?



