`

java浅复制和深复制

阅读更多
  • 浅复制

被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。

看下面的例子

School类

public class School implements Cloneable{
	private String name;
	public School(String name){
		this.name = name;
	}
	@Override
	public String toString() {
		return name;
	}
	@Override
	protected Object clone() throws CloneNotSupportedException {
		return super.clone();
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
}

Student类

public class Student implements Cloneable{
	private int age;
	private School school;
	
	public Student(){
		System.out.println("init...");
	}
	
	@Override
	protected Object clone() throws CloneNotSupportedException {
		Student cloneStudent = (Student)super.clone();
		return cloneStudent;
	}
	
	@Override
	public String toString() {
		return "age:"+age+" school:"+school;
	}
	
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public School getSchool() {
		return school;
	}
	public void setSchool(School school) {
		this.school = school;
	}
}

测试代码

                Student s1 = new Student();
		s1.setAge(20);
		s1.setSchool(new School("java school"));
		System.out.println("before clone s1 value is "+s1);
		Student s2 = (Student)s1.clone();
		s2.setAge(18);
		s2.getSchool().setName("c++ school");
		System.out.println("after clone s1 value is "+s1);
		System.out.println("after clone s2 value is "+s2);

运行结果

init...
before clone s1 value is age:20 school:java school
after clone s1 value is age:20 school:c++ school
after clone s2 value is age:18 school:c++ school

由s1对象克隆来的s2对象,两个对象的成员变量school有相同的引用。

 

  • 深复制

被复制对象的所有变量都含有与原来的对象相同的值,除去那些引用其他对象的变量。那些引用其他对象的变量将指向被复制过的新对象,而不再是原有的那些被引用的对象。深复制把要复制的对象所引用的对象都复制了一遍。

将Student类的clone方法改为

        @Override
	protected Object clone() throws CloneNotSupportedException {
		Student cloneStudent = (Student)super.clone();
		cloneStudent.setSchool((School)this.school.clone());
		return cloneStudent;
	}

运行结果

init...
before clone s1 value is age:20 school:java school
after clone s1 value is age:20 school:java school
after clone s2 value is age:18 school:c++ school

 

  • 使用串行化实现深复制

Student和School实现Serializable接口

Student添加方法

	public Object deepClone() throws IOException, ClassNotFoundException {
		// 将对象写到流里
		ByteArrayOutputStream bo = new ByteArrayOutputStream();
		ObjectOutputStream oo = new ObjectOutputStream(bo);
		oo.writeObject(this);
		// 从流里读出来
		ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray());
		ObjectInputStream oi = new ObjectInputStream(bi);
		return (oi.readObject());
	}

测试代码

		Student s1 = new Student();
		s1.setAge(20);
		s1.setSchool(new School("java school"));
		System.out.println("before clone s1 value is "+s1);
		Student s2 = (Student)s1.deepClone();
		s2.setAge(18);
		s2.getSchool().setName("c++ school");
		System.out.println("after clone s1 value is "+s1);
		System.out.println("after clone s2 value is "+s2);

运行结果

init...
before clone s1 value is age:20 school:java school
after clone s1 value is age:20 school:java school
after clone s2 value is age:18 school:c++ school

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics