深淺複製及序列化

實現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();
	}
}
相關文章
相關標籤/搜索