关于对象的深度复制和浅度复制

本文详细探讨了Java中深克隆与浅克隆的区别,并通过三种不同的方法实现了HashMap对象的复制,包括使用Cloneable接口、putAll方法及对象流复制,最后验证了只有对象流复制才能达到深度克隆的效果。

java深度clone比较全面的帖子:http://blog.youkuaiyun.com/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
这种方式就是深度复制。这样可以实现对象的分离和数据操作不会出异常。




评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值