共计 1907 个字符,预计需要花费 5 分钟才能阅读完成。
问题引入
须要将不同的两个对象实例进行属性复制,从而基于源对象的属性信息进行后续操作,而不扭转源对象的属性信息, 比方 DTO 数据传输对象和数据对象 DO,咱们须要将 DO 对象进行属性复制到 DTO,然而对象格局又不一样,所以咱们须要编写映射代码将对象中的属性值从一种类型转换成另一种类型。
这种转换最原始的形式就是手动编写大量的 get/set
代码,当然这是咱们开发过程不违心去做的,因为它的确显得很繁琐。为了解决这一痛点,就诞生了一些不便的类库,罕用的有 apache 的 BeanUtils
,spring 的 BeanUtils
,这些库能够帮忙咱们轻松的实现对象属性的拷贝而不须要咱们再手动 get/set.
在介绍之前,咱们先来看下对于对象拷贝的前置常识,浅拷贝和深拷贝。
前置常识
如果在拷贝这个对象的时候,只对根本数据类型进行了拷贝,而对援用数据类型只是进行援用的传递,而没有实在的创立一个新的对象,则认为是 浅拷贝 。反之,在对援用数据类型进行拷贝的时候,创立了一个新的对象,并且复制其内的成员变量,则认为是 深拷贝。
简略来说:
- 浅拷贝:对根本数据类型进行值传递,对援用数据类型进行援用传递般的拷贝,此为浅拷贝
- 深拷贝:对根本数据类型进行值传递,对援用数据类型,创立一个新的对象,并复制其内容,此为深拷贝。
BeanUtils
Apache 的 BeanUtils
beantutils 对于对象拷贝加了很多的测验,包含类型的转换,甚至还会测验对象所属的类的可拜访性, 堪称相当简单,这也造就了它的差劲的性能,在 Java 开发手册中也提到尽量避免应用 Apache 的 BeanUtils 工具类。
应用案例(留神参数的程序)
public class PersonSource {
private Integer id;
private String username;
private String password;
private Integer age;
// getters/setters omiited
}
public class PersonDest {
private Integer id;
private String username;
private Integer age;
// getters/setters omiited
}
public class TestApacheBeanUtils {public static void main(String[] args) throws InvocationTargetException, IllegalAccessException {
// 上面只是用于独自测试
PersonSource personSource = new PersonSource(1, "pjmike", "12345", 21);
PersonDest personDest = new PersonDest();
BeanUtils.copyProperties(personDest,personSource);
System.out.println("persondest:"+personDest);
}
}
persondest: PersonDest{id=1, username='pjmike', age=21}
Spring 的 BeanUtils
spring 下的 BeanUtils 也是应用 copyProperties
办法进行拷贝,只不过它的实现形式非常简单,就是对两个对象中雷同名字的属性进行简略的 get/set,仅查看属性的可拜访性。
应用案例(留神参数的程序,和 Apache 相同)
public class TestSpringBeanUtils {public static void main(String[] args) throws InvocationTargetException, IllegalAccessException {
// 上面只是用于独自测试
PersonSource personSource = new PersonSource(1, "pjmike", "12345", 21);
PersonDest personDest = new PersonDest();
BeanUtils.copyProperties(personSource,personDest);
System.out.println("persondest:"+personDest);
}
}
小结
以上简要的剖析两种 BeanUtils,因为 Apache 下的 BeanUtils 性能较差,不倡议应用,能够应用 Spring 的 BeanUtils, 或者应用其余拷贝框架,比方 cglib BeanCopier, 基于 javassist 的 Orika 等,这些也是十分优良的类库。留神这种都是浅拷贝!!!