1.深拷贝与浅拷贝
浅拷贝
常见以下代码
User a = new User();
a.name="王二";
User b =a ;
b.name="李四";
User c =a ;
System.out.println(a.name);
System.out.println(b.name);
用=的方式赋值一个对象等于另一个对象,就是一个浅拷贝。此时b和c的内存地址指向同一个对象,改变c的属性的同时也会改变b的属性。有的时候我们需要一个深拷贝对象。
深拷贝
两个对象的所有的属性的值都一样,但是他们在内存中是不同的对象,这就是一个深拷贝。
当我们需要处理一个新对象、但是新对象的所有默认值跟旧对象一致时,为了不影响修改新对象对老对象造成的影响,我们就需要深拷贝了。
如何实现深拷贝?
一般情况下,使用属性的get、set方法给对应的属性赋值,但是如果对象很大很复杂,这总方式太麻烦,工作量很大。
1.通过流读取对象为byte[]数组
代码如下:
User user = new User();
user.name="张三";
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(user);
oos.flush();
byte[] bytes= bos.toByteArray();
ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
ObjectInputStream ois = new ObjectInputStream(bis);
User user1 =(User) ois.readObject();
System.out.println(user1.name);
System.out.println(user1==user);
这种情况下要求对象实现序列化接口。这种方式目前没发现问题,适用各种场景,代码也比较通用,而且可以把byte存入数据库或redis,方便在分布式的场景中还原对象。
2.通过json实现
这里先不贴代码了,就是把对象转换成json字符串,然后再把字符串转换成对象。
但是这一种方式有一个问题,代码如下:
public class User2 {
List<User> userList;
Map<String,User> userMap;
}
如果userList里的对象与usermap的对象是同一个user对象,那么在通过json转换回来的时候可能就变成了不同的user对象。
3.,mapStrust实现
mapStrust是为了解决从数据库实体类转化成DTO的开发工具类,因为spring的BeanUtils是通过反射实现的,所以效率存在优化空间,我们定义好一个mapStrust的接口和方法,mapStrust就帮我们生成一个实现类生成对象之间转换的类,因此也可以用来拷贝对象。具体使用方法以后再补充。