一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第12天,点击查看活动详情
简介
我们在开发中经常遇到,把父类的属性拷贝到子类中。通常有2种方法:
- 一个一个set
- 用BeanUtils.copyProperties
很显然BeanUtils更加方便,也美观很多。
==值得注意的是BeanUtils.copyProperties有俩个spring,apache不同的包,不同的包中BeanUtils的方法使用是不一样的。==
//org.springframework.beans.BeanUtils
public static void copyProperties(Object source, Object target){....}
//org.apache.commons.beanutils.BeanUtils
public static void copyProperties(Object dest,Object orig){....}
区别
- 在spring包下的copyProperties第一个参数是被copy的对象,而apache中是第二个参数,所以使用时不要弄混。
- 使用apache的进行copy对象时,被copy的对象(source/orig)中包含的字段目标对象(target/dest)必须包含,可以有其他的多于字段,类型可以不相同,但字段名称必须一致,spring中的没有这个限制。
深浅拷贝问题
BeanUtils.copyProperties使用起来虽然方便,==但是它其实只是浅拷贝==,所以类中都是单一的属性,如果类中包含有其他的子类就需要考虑下拷贝后目标对象(target/dest)中包含被copy的对象(source/orig)中的子类是否有可能被修改,如果有可能被修改就不能直接使用。
这里介绍一种深拷贝的方法,先将集合转化为字节数组输出流,然后在读取,这样就可以实现深度拷贝,代码如下:
public <T> List<T> deepCopy(List<T> src) throws IOException, ClassNotFoundException {
// 将该对象序列化成流,因为写在流里的是对象的一个拷贝,而原对象仍然存在于JVM里面。所以利用这个特性可以实现对象的深拷贝
ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(byteOut);
out.writeObject(src);
ByteArrayInputStream byteIn = new ByteArrayInputStream(byteOut.toByteArray());
ObjectInputStream in = new ObjectInputStream(byteIn);
@SuppressWarnings("unchecked")
List<T> dest = (List<T>) in.readObject();
return dest;
}