實現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(); } }