オブジェクトの深度コピーと浅さコピーについて

5149 ワード

JAvaの深さcloneの比較的包括的な投稿:http://blog.csdn.net/randyjiawenjie/article/details/7563323
コンセプト
デプスコピーデプスコピー:コンテンツが一致し、コンテンツオブジェクトが一致しません.つまり、オブジェクトが作成されたときに新しく作成されたオブジェクトです.
浅いレプリケーション:コンテンツが一致し、コンテンツオブジェクトが一致します.
シーン
たとえば、HashMapオブジェクトを例にとると、レプリケーションを実現するには3つの方法があります.
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
この方法は、深さレプリケーションである.これにより、オブジェクトの分離やデータ操作に異常が発生しないようにすることができます.