關於對象的深度複製和淺度複製

java深度clone比較全面的帖子:http://blog.csdn.net/randyjiawenjie/article/details/7563323

概念

深度複製:內容一致,內容對象不一致,也就是說對象時新創建的對象
淺度複製:內容一致,內容對象一致

場景

例如以HashMap對象爲例,實現複製有三種方式:

1、Cloneable對象來使用clone;

2、putAll方式

3、対向流copy


方式一、clone

import java.io.Serializable;
public class MySerializable implements Serializable {
	private int id;

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

}
測試代碼如下
import java.util.HashMap;
public class SerializableDeepCopy {
	public static void main(String[] args) {
		HashMap<String, MySerializable> mySerializableMap = new HashMap<String, MySerializable>();
		MySerializable ms = new MySerializable();
		ms.setId(1);
		mySerializableMap.put("test", ms);
		HashMap<String, MySerializable> mySerializableMapClone = (HashMap<String, MySerializable>) mySerializableMap
				.clone();
		if (mySerializableMap == mySerializableMapClone) {
			System.out.println("mySerializableMap == mySerializableMapClone");
		} else {
			System.out.println("mySerializableMap != mySerializableMapClone");
		}
		if (mySerializableMap.get("test") == mySerializableMapClone.get("test")) {
			System.out
					.println("mySerializableMap test value == mySerializableMapClone test value");
		} else {
			System.out
					.println("mySerializableMap test value != mySerializableMapClone test value");
		}
	}
}
系統輸出結果:

mySerializableMap != mySerializableMapClone
mySerializableMap test value == mySerializableMapClone test value
從輸出可以看出系統是對象的實體內容是一致的,這就說明HashMap所做的是一種淺度複製,淺度複製在併發操作的時候容易出現數據一致性和併發迭代操作異常

方式二、putAll

public class SerializableDeepCopy {
	public static void main(String[] args) {
		HashMap<String, MySerializable> mySerializableMap = new HashMap<String, MySerializable>();
		MySerializable ms = new MySerializable();
		ms.setId(1);
		mySerializableMap.put("test", ms);
		HashMap<String, MySerializable> mySerializableMapClone = new HashMap<String, MySerializable>();
		mySerializableMapClone.putAll(mySerializableMap);
		if (mySerializableMap == mySerializableMapClone) {
			System.out.println("mySerializableMap == mySerializableMapClone");
		} else {
			System.out.println("mySerializableMap != mySerializableMapClone");
		}
		if (mySerializableMap.get("test") == mySerializableMapClone.get("test")) {
			System.out
					.println("mySerializableMap test value == mySerializableMapClone test value");
		} else {
			System.out
					.println("mySerializableMap test value != mySerializableMapClone test value");
		}
	}
}
輸出結果如下:

mySerializableMap != mySerializableMapClone
mySerializableMap test value == mySerializableMapClone test value
結果仍然不理想,還是淺度複製

方式三、字節流複製

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.HashMap;
public class SerializableDeepCopy {
	public static void main(String[] args) {
		HashMap<String, MySerializable> mySerializableMap = new HashMap<String, MySerializable>();
		MySerializable ms = new MySerializable();
		ms.setId(1);
		mySerializableMap.put("test", ms);
		HashMap<String, MySerializable> mySerializableMapClone = clone(mySerializableMap);
		if (mySerializableMap == mySerializableMapClone) {
			System.out.println("mySerializableMap == mySerializableMapClone");
		} else {
			System.out.println("mySerializableMap != mySerializableMapClone");
		}
		if (mySerializableMap.get("test") == mySerializableMapClone.get("test")) {
			System.out
					.println("mySerializableMap test value == mySerializableMapClone test value");
		} else {
			System.out
					.println("mySerializableMap test value != mySerializableMapClone test value");
		}
	}
	
	@SuppressWarnings("unchecked")
	private static  <T extends Serializable> T clone(T obj) {
		T clonedObj = null;
		try {
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			ObjectOutputStream oos = new ObjectOutputStream(baos);
			oos.writeObject(obj);
			oos.close();

			ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
			ObjectInputStream ois = new ObjectInputStream(bais);
			clonedObj = (T) ois.readObject();
			ois.close();

		} catch (Exception e) {
			e.printStackTrace();
		}

		return clonedObj;
	}
}
輸出結果如下:

mySerializableMap != mySerializableMapClone
mySerializableMap test value != mySerializableMapClone test value
這種方式就是深度複製。這樣可以實現對象的分離和數據操作不會出異常。




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章