Java浅复制和深复制

简述:

1. 研究一下Java中浅复制和深复制的区别及一些特性

2.分别用普通的clone方法和串行化(Serialization)方法实现深复制


浅复制:

被复制对象的所有变量都含有与原来的对象相同的值,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象。


深复制:

被复制对象的所有变量都含有与原来的对象相同的值,  同时复制它所引用的所有对象


测试1(普通的clone()方法实现深复制

深复制的实现, Person类中有一个PersonInfo的成员,用来表示Person的信息,重写了Clone()的方法之后, 形成了深复制,

person1.clone()的过程中,新建了一个person1所引用的personInfo对象,并把包括引用在内生成的一个新的对象传给了person2

之后修改person1的personInfo, 并不影响person2中的personInfo的信息(因为person2 中的personInfo是新建的一个对象,同时被

person2 的personInfo引用了)

其实就是在clone函数中新增一个对clone对象的成员的新的引用的创建

o.personInfo = (PersonInfo)personInfo.clone();


PersonInfo.java

package test.deep.clone;

public class PersonInfo implements Cloneable{
	private String name;
	private int age;
	PersonInfo(String name, int age){
		this.name = name;
		this.age = age;
	}
	@Override
	protected Object clone() throws CloneNotSupportedException {
		Object o = null;
		try{
			o = super.clone();
		}catch(CloneNotSupportedException e){
			System.out.println(e.toString());
		}
		return o;
	}
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	
}



Person.java

package test.deep.clone;

public class Person implements Cloneable{
	private PersonInfo personInfo;
	Person(PersonInfo personInfo){
		this.personInfo = personInfo;
	}
	public PersonInfo getPersonInfo() {
		return personInfo;
	}

	public void setPersonInfo(PersonInfo personInfo) {
		this.personInfo = personInfo;
	}
	@Override
	protected Object clone() throws CloneNotSupportedException {
		Person o = null;
		try{
			o = (Person)super.clone();
		}catch(CloneNotSupportedException e){
			System.out.println(e.toString());
		}
		o.personInfo = (PersonInfo)personInfo.clone();
		return o;
	}
}

Test.java(测试)

package test.deep.clone;

public class Test {
	public static void main(String[] args) {
		PersonInfo personInfo1 = new PersonInfo("Peter", 20);
		Person person1 = new Person(personInfo1);
		Person person2 = null;
		try {
			person2 = (Person) person1.clone();
		} catch (CloneNotSupportedException e) {
			System.out.println(e.toString());
		}
		//change the personInfo of person1 
		person1.setPersonInfo(new PersonInfo("John", 30));
		System.out.println("person1=>  name: " + person1.getPersonInfo().getName() + ", age: " 
				+ person1.getPersonInfo().getAge());
		//Due to the deep duplication of person1, the previous personInfo modification on person1
		//didn't have any effect on person2 (person2 is a new Object from clone);
		System.out.println("person2=>  name: " + person2.getPersonInfo().getName() + ", age: " 
				+ person2.getPersonInfo().getAge());
	}
}

测试一普通clone()输出:

由于是新建了一个person2对象,及其personInfo的新的引用所以在修改该person1中personInfo变量的时候,对person2无影响




测试2

使用串行化(Serialization)实现深复制

(串行化:对象通过写出描述自己状态的数值来记录自己,这个过程叫对象的串行化)

PersonInfo.java

package test.clone.deep.serialization;

import java.io.Serializable;

public class PersonInfo implements Serializable{
	private static final long serialVersionUID = 1L;
	private String name;
	private int age;
	PersonInfo(String name, int age){
		this.name = name;
		this.age = age;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
}

Person.java

package test.clone.deep.serialization;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

public class Person implements Serializable{
	private static final long serialVersionUID = 1L;
	private int id ; 
	private PersonInfo personInfo;
	Person(int id, PersonInfo personInfo){
		this.id = id;
		this.personInfo = personInfo;
	}
	
	public void setId(int id) {
		this.id = id;
	}
	
	public int getId() {
		return id;
	}
	
	public PersonInfo getPersonInfo() {
		return personInfo;
	}

	public void setPersonInfo(PersonInfo personInfo) {
		this.personInfo = personInfo;
	}
	
	public Object DeepClone(){
		//write the object to stream
		ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
		ObjectOutputStream objectOutputStream = null;
		try {
			objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
		} catch (IOException e) {
			System.out.println("ObjectOutputStream open fail! ");
		}
		try {
			objectOutputStream.writeObject(this);
		} catch (IOException e) {
			System.out.println("ObjectOutputStream write object fail! ");
		}
		
		//read the object from stream
		Object o = null;
		ByteArrayInputStream byteArrayInputStream 
		    = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
		ObjectInputStream objectInputStream = null;
		try {
			objectInputStream = new ObjectInputStream(byteArrayInputStream);
		} catch (IOException e) {
			System.out.println("ObjectInputStream open fail! ");
		}
		try {
			o = objectInputStream.readObject();
		} catch (IOException e) {
			System.out.println("ObjectInputStream read object fail! ");
		} catch (ClassNotFoundException e) {
			System.out.println("ObjectOutputStream class not found!");
		}
		return o;
	}
}

Test.java

package test.clone.deep.serialization;

public class Test {
	public static void main(String[] args) {
		System.out.println("Serialization implements deep clone: ");
		PersonInfo personInfo1 = new PersonInfo("Peter", 20);
		Person person1 = new Person(1, personInfo1);
		Person person2 = null;
		person2 = (Person) person1.DeepClone();
		person2.setId(2);
		//change the personInfo of person1 
		person2.setPersonInfo(new PersonInfo("John", 30));
		System.out.println("person1=>  id: " + person1.getId() 
				+ ", name: " + person1.getPersonInfo().getName() + ", age: " 
				+ person1.getPersonInfo().getAge());
		//Due to the deep duplication of person1, the previous personInfo modification on person1
		//didn't have any effect on person2 (person2 is a new Object from clone);
		System.out.println("person2=>  id: " + person2.getId() 
				+ ", name: " + person2.getPersonInfo().getName() + ", age: " 
				+ person2.getPersonInfo().getAge());
	}
}

串行化实现深复制输出:



你可能感兴趣的:(Java浅复制和深复制)