java对象的浅拷贝和深拷贝

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

public class Student implements Cloneable, Serializable {

	int id;

	Map<String, String> score = new HashMap<String, String>();

	public Student(int id, Map<String, String> score) {
		super();
		this.id = id;
		this.score = score;
	}

	/**
	 * 浅拷贝是按位拷贝对象,它会创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝。如果属
	 * 性是基本类型,拷贝的就是基本类型的值;如果属性是内存地址(引用类型),拷贝的就是内存地址 ,
	 * 因此如果其中一个对象改变了这个地址,就会影响到另一个对象。
	 */
	@Override
	protected Object clone() throws CloneNotSupportedException {
		// TODO 自动生成的方法存根
		return super.clone();
	}

	/**
	 * 
	 * 深拷贝会拷贝所有的属性,并拷贝属性指向的动态分配的内存。当对象和它所引用的对象一起拷贝时即发生
	 * 深拷贝。深拷贝相比于浅拷贝速度较慢并且花销较大。
	 */
	protected Object deepClone() throws CloneNotSupportedException,
			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();

	}

}


import java.io.IOException;
import java.util.HashMap;
import java.util.Map;


public class T {

	/**
	 * @param args
	 * @throws CloneNotSupportedException 
	 * @throws ClassNotFoundException 
	 * @throws IOException 
	 */
	public static void main(String[] args){
		// TODO 自动生成的方法存根
		
		try {
			Map<String,String> score =new HashMap<String,String>();
			score.put("English", "139");
			score.put("Math", "146");

			Student s1=new Student(1,score);
			Student s2=(Student) s1.clone();//浅拷贝
			Student s3=(Student) s1.deepClone();//深拷贝
			
			s1.score.put("Chinese", "147");
			
			System.out.println(s2.score.get("Math")+" "+s2.score.get("Chinese"));//139 147
			System.out.println(s3.score.get("Math")+" "+s3.score.get("Chinese"));//139 null
			
		} catch (Exception e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		}
	}
}

猜你喜欢

转载自xiongjiajia.iteye.com/blog/2321818