你还在用BeanUtils进行对象属性拷贝?
在做业务的时候,为了隔离变化,我们会将DAO
查询出来的DO
和对前端提供的DTO
隔离开来。大概90%
的时候,它们的结构都是类似的;但是我们很不喜欢写很多冗长的b.setF1(a.getF1())
这样的代码,于是我们需要简化对象拷贝方式。
一、背景
1.1 对象拷贝概念
Java
中,数据类型分为值类型(基本数据类型)和引用类型,值类型包括int
、double
、byte
、boolean
、char
等简单数据类型,引用类型包括类、接口、数组等复杂类型。
对象拷贝分为浅拷贝(浅克隆)与深拷贝(深克隆)。
- 浅拷贝与深拷贝差异
分类 | 浅拷贝 | 深拷贝 |
---|---|---|
区别 | 创建一个新对象,然后将当前对象的非静态字段复制到该新对象,如果字段是值类型的,那么对该字段执行复制;如果该字段是引用类型的话,则复制引用但不复制引用的对象。因此,原始对象及其副本引用同一个对象。 | 创建一个新对象,然后将当前对象的非静态字段复制到该新对象,无论该字段是值类型的还是引用类型,都复制独立的一份。当你修改其中一个对象的任何内容时,都不会影响另一个对象的内容。 |
1.2 示例前准备
- 源对象属性类
UserDO.class
(以下示例,源对象都用这个)
@Data public class UserDO { private int id; private String userName; /** * 以下两个字段用户模拟自定义转换 */ private LocalDateTime gmtBroth; private BigDecimal balance; public UserDO(Integer id, String userName, LocalDateTime gmtBroth, BigDecimal balance) { this.id = id; this.userName = userName; this.gmtBroth = gmtBroth; this.balance = balance; } }
- 造数据工具类
DataUtil.class
public class DataUtil { /** * 模拟查询出一条数据 * @return */ public static UserDO createData() { return new UserDO(1, "Van", LocalDateTime.now(),new BigDecimal(100L)); } /** * 模拟查询出多条数据 * @param num 数量 * @return */