概念
浅拷贝:
对基本数据类型进⾏值传递,对引⽤数据类型进⾏引⽤传递般的拷⻉,此为浅拷⻉。
深拷贝:
对基本数据类型进⾏值传递,对引⽤数据类型,创建⼀个新的对象,并复制其内容,此
为深拷⻉。
浅拷贝实现
- 调用clone方法
注意:调用对象的 clone 方法,必须要让类实现 Cloneable 接口,并且覆写 clone 方法。
public class Demo implements Cloneable{
public String demo;
public Demo(String demo){
this.demo = demo;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
public static voi main(String[] args) {
Demo d1 = new Demo("demo");
Demo d2 = (Demo) d1.clone();
}
}
如上图,d1调用clone()方法把值引用传递给d2,修改d2时也会改d1的值。
浅拷贝实例
java-List复制-浅拷贝实例
- 遍历循环复制
List<Dome> destList=new ArrayList<Dome>(srcList.size()); for(Dome p : srcList){ destList.add(p); }
2.使用list实现类的构造方法
List<Dome> destList=new ArrayList<Dome>(srcList);
3.使用list.addAll()方法
List<Dome> destList=new ArrayList<Dome>(); destList.addAll(srcList);
4.使用System.arraycopy()方法
Dome[] srcDomes=srcList.toArray(new Dome[0]); Dome[] destDomes=new Dome[srcDomes.length]; System.arraycopy(srcDomes, 0, destDomes, 0, srcDomes.length);
5.Collections.copy()
Collections.copy(destList, srcList);
6.Java 8 Stream APIs
List < String > copy = srcList.stream().collect(Collectors.toList());
深拷贝实现
1、让每个引用类型属性内部都重写clone() 方法
2、使用序列化(推荐)
序列化是将对象写到流中便于传输,而反序列化则是把对象从流中读取出来。这里写到流中的对象则是原始对象的一个拷贝,因为原始对象还存在 JVM 中,所以我们可以利用对象的序列化产生克隆对象,然后通过反序列化获取这个对象。
注意每个需要序列化的类都要实现 Serializable 接口,如果有某个属性不需要序列化,可以将其声明为 transient,即将其排除在克隆属性之外。
因为序列化产生的是两个完全独立的对象,所有无论嵌套多少个引用类型,序列化都是能实现深拷贝的。
//深度拷贝
public Object deepClone(Object o) throws Exception{
// 序列化
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(o);
// 反序列化
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);
return ois.readObject();
}