Java中浅拷贝和深拷贝的区别

深拷贝和浅拷贝的区别

浅拷贝:被拷贝的对象的所有属性值都与原来的对象相同,而对象的所有属性引用仍然指向原来的属性所指向的内存地址。需要注意的是cloneObj == obj 返回的是false,所以使用的Object的clone()是浅拷贝。

深拷贝:被拷贝的对象的所有属性值都与原来的对象相同,而对象的所有属性的引用都指向新的克隆出来的属性的内存地址。

浅拷贝的实现方式

public class Test implements Cloneable{
          
   
	
	@Override
	protected Object clone() throws CloneNotSupportedException {
          
   
		return super.clone();
	}
	
}

深拷贝的实现方式

深拷贝的实现方式一般有三种,第一种是使用构造器来实现,这个先不说

第二种是使用clone()方法来实现

public class Test implements Cloneable {
          
   
	
	private SubTest subTest;
	
	@Override
	protected Object clone() {
          
   
		Object obj = null;
		try {
          
   
			obj = super.clone();
			Test cloneTest = (Test) obj;
			Object subObj = cloneTest.subTest.clone();
			SubTest cloneSubTest = (SubTest) subObj;
			cloneTest.setSubTest(cloneSubTest);
		} catch (CloneNotSupportedException e) {
          
   
			e.printStackTrace();
		}
		return obj;
	}
	
	public void setSubTest(SubTest subTest) {
          
   
		this.subTest = subTest;
	}
	
}

第三种方法是使用序列化来进行深拷贝

SubTest

import java.io.Serializable;

public class SubTest implements Cloneable, Serializable {
          
   
	@Override
	protected Object clone() throws CloneNotSupportedException {
          
   
		return super.clone();
	}
}

Test

public class Test implements Cloneable, Serializable {
          
   
	
	private SubTest subTest;
	
	
	
	// 使用clone()进行深拷贝
	@Override
	protected Object clone() {
          
   
		Object obj = null;
		try {
          
   
			obj = super.clone();
			Test cloneTest = (Test) obj;
			Object subObj = cloneTest.subTest.clone();
			SubTest cloneSubTest = (SubTest) subObj;
			cloneTest.setSubTest(cloneSubTest);
		} catch (CloneNotSupportedException e) {
          
   
			e.printStackTrace();
		}
		return obj;
	}
	
	
	// 使用序列化方式来实现深拷贝
	public Object deepClone() throws Exception {
          
   
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		ObjectOutputStream oos = new ObjectOutputStream(baos);
		oos.writeObject(this);
		
		ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
		ObjectInputStream ois = new ObjectInputStream(bais);
		return ois.readObject();
	}
	
	public void setSubTest(SubTest subTest) {
          
   
		this.subTest = subTest;
	}
	
	public SubTest getSubTest() {
          
   
		return subTest;
	}
}
经验分享 程序员 微信小程序 职场和发展