深浅复制及序列化

实现Cloneable接口的clone() 便可实现对象克隆,实现Serializable接口可以使对象支持序列化,网上查了下相关资料,clone针对基本类型属性没有问题,但对引用类型时默认只能浅复制,复制的是引用的地址,实现深复制时比较麻烦。本身作了个练习小试一番。dom

public class TestClone {
/**
 * 浅复制简单对象(仅包含基本类型属性)
 */
@Test
public void shallowCloneSimpleObject() {
	Domain da = new Domain(2, "Zhangsan");
	try {
		Object db = da.clone();
		System.out.println(da.toString());
		System.out.println(db.toString());
	} catch (CloneNotSupportedException e) {
		e.printStackTrace();
	}
	
	/**
	 * 打印结果:
	 *          obj.age=2,obj.name.hashCode=-1367991180,obj.hashCode=11352996
			    obj.age=2,obj.name.hashCode=-1367991180,obj.hashCode=19313225
	        结果分析:
	                               基本类型Clone(克隆)没问题。
	 */
}

/**
 * 浅复制复杂对象(包含引用类型属性)
 */
@Test
public void shallowCloneComplexObject() {
	DomainW da = new DomainW();
	try {
		Object db = da.clone();
		System.out.println(da.toString());
		System.out.println(db.toString());
	} catch (CloneNotSupportedException e) {
		e.printStackTrace();
	}
	
	/**
	 * 打印结果:
	 *          obj.domain.hashCode=11352996
			    obj.domain.hashCode=11352996
	        结果分析
	                               基本类型Clone(克隆)没问题,但引用类型Clone的是引用的地址。
	 */
}

/**
 * 深复制对象
 */
@Test
public void deepClone() {
	DomainX da = new DomainX();
	try {
		Object db = da.clone();
		System.out.println(da.toString());
		System.out.println(db.toString());
	} catch (CloneNotSupportedException e) {
		e.printStackTrace();
	}
	/**
	 * 打印结果:
	 *          obj.domain.hashCode=19313225
				obj.domain.hashCode=25358555
	        结果分析:
	            Clone复杂对象,对引用类型的属性须要再次Clone或实例化。
	 */
}

/**
 * 序列化/反序列化复制对象
 */
@Test
public void serializeClone() {
	DomainY da = new DomainY();
	ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
	try {
		/**序列化对象             BEGIN*/
		ObjectOutputStream objOs = new ObjectOutputStream(byteOut);
		objOs.writeObject(da);
		/**序列化对象                  END*/
		
		/**反序列化对象        BEGIN*/
		ByteArrayInputStream byteIn = new ByteArrayInputStream(byteOut.toByteArray());
		ObjectInputStream objIs = new ObjectInputStream(byteIn);
		Object db = objIs.readObject();
		/**反序列化对象             END*/
		System.out.println(da.toString());
		System.out.println(db.toString());
	} catch (IOException e) {
		e.printStackTrace();
	} catch (ClassNotFoundException e) {
		e.printStackTrace();
	}
	/**
	 * 打印结果:
	 *          obj.domain.hashCode=23065739
				obj.domain.hashCode=12115735
	        结果分析:
	        	利用序列化机制能够实现复杂对象的深复制。
	 */
	
}
}

/**
 * 测试浅复制实体
 * 	       实现Cloneable和Serializable接口
 */
class Domain implements Cloneable,Serializable{
	
	private static final long serialVersionUID = -582678566899393941L;
	private int age;
	private String name;

	public Domain() {

	}
	
	public Domain(int age, String name) {
		this.age = age;
		this.name = name;
	}
	
	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	protected Object clone() throws CloneNotSupportedException {
		return super.clone();
	}

	@Override
	public String toString() {
		return "obj.age="+this.getAge()+",obj.name.hashCode="+this.name.hashCode()+",obj.hashCode="+this.hashCode();
	}
}

/**
 * 测试深复制实体
 * 	       实现Cloneable接口
 */
class DomainW implements Cloneable{
	
	private Domain domain = new Domain();
	
	
	public DomainW() {
		
	}
	
	public Domain getDomain() {
		return domain;
	}

	public void setDomain(Domain domain) {
		this.domain = domain;
	}

	@Override
	protected Object clone() throws CloneNotSupportedException {
		return super.clone();
	}

	@Override
	public String toString() {
		return "obj.domain.hashCode="+this.domain.hashCode();
	}
}

/**
 * 测试深复制实体
 * 	       实现Cloneable接口
 */
class DomainX implements Cloneable{
	
	private Domain domain = new Domain();
	
	
	public DomainX() {
		
	}
	
	public Domain getDomain() {
		return domain;
	}

	public void setDomain(Domain domain) {
		this.domain = domain;
	}

	protected Object clone() throws CloneNotSupportedException {
		DomainX clone = (DomainX) super.clone();
		clone.setDomain((Domain)clone.getDomain().clone());
		//clone.setDomain(new Domain());
		return clone;
	}

	@Override
	public String toString() {
		return "obj.domain.hashCode="+this.domain.hashCode();
	}
}

/**
 * 测试序列化实现深复制实体
 * 	       实现Cloneable和Serializable接口
 */
class DomainY implements Serializable{
	private static final long serialVersionUID = 7360119346665988338L;
	private Domain domain = new Domain();
	
	public DomainY() {
		
	}
	
	public Domain getDomain() {
		return domain;
	}

	public void setDomain(Domain domain) {
		this.domain = domain;
	}
	
	@Override
	public String toString() {
		return "obj.domain.hashCode="+this.domain.hashCode();
	}
}
相关文章
相关标签/搜索