实现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(); } }