package com.pachira.c; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; /* * Java的浅拷贝和深拷贝 * 【浅拷贝】:重写Object的clone()方法且实现Cloneable这个空接口(规则如下): * +---------------------------------------------------------------------------------------------+ * | 基本类型 | 拷贝其值,比如int、float等。 | * +---------------------------------------------------------------------------------------------+ * | String | 拷贝其地址引用,但在修改时,它从字符串池中重新生成一个新字符串,原有字符串对象保持不变。 | * +---------------------------------------------------------------------------------------------+ * | 对象 | 拷贝其地址引用,也就是说此时新对象与原来对象是公用该实例变量。 | * +---------------------------------------------------------------------------------------------+ * * 【深拷贝】:利用序列化实现对象的拷贝: * 原理:把母对象写入到一个字节流中,再从字节流中将其读出来,这样就可以创建一个新的对象了,并且该新对象与母对象之间并不存在引用共享的问题,真正实现对象的深拷贝。 * 注意:被克隆的对象需要实现Serializable接口 * * 参考: * http://cmsblogs.com/?p=58 * http://www.cnblogs.com/chenssy/p/3308489.html */ public class LClone implements Cloneable, Serializable{ private static final long serialVersionUID = -1991475817161553683L; private int id; private String name; private Email email; public LClone() { } public LClone(int id, String name, Email email) { this.id = id; this.name = name; this.email = email; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Email getEmail() { return email; } public void setEmail(Email email) { this.email = email; } public LClone clone() throws CloneNotSupportedException { return (LClone)super.clone(); } @Override public String toString() { return "id: " + this.id + ", name: " + this.name + ", email: " + this.email; } public static void main(String[] args) throws CloneNotSupportedException { Email email = new LClone.Email("welcome."); LClone stu = new LClone(2, "Tom", email); LClone stu2 = stu.clone(); stu2.setId(3); stu2.setName("Jim"); System.out.println(stu); System.out.println(stu2); System.out.println(stu.getEmail() == stu2.getEmail()); CloneUtil cloneUtil = new LClone.CloneUtil(); LClone stu3 = cloneUtil.clone(stu); System.out.println(stu.getEmail() == stu3.getEmail()); // id: 2, name: Tom, email: welcome. // id: 3, name: Jim, email: welcome. // true // false } static class Email implements Serializable{ private static final long serialVersionUID = 717077025366523218L; private String content; public String getContent() { return content; } public void setContent(String content) { this.content = content; } public Email(String content) { this.content = content; } @Override public String toString() { return this.content; } } static class CloneUtil { @SuppressWarnings("unchecked") public <T extends Serializable> T clone(T obj){ T newT = null; try { //写入字节流 ByteArrayOutputStream out = new ByteArrayOutputStream(); ObjectOutputStream obs = new ObjectOutputStream(out); obs.writeObject(obj); obs.close(); //分配内存,写入原始对象,生成新对象 ByteArrayInputStream bais = new ByteArrayInputStream(out.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bais); //返回生成的新对象 newT = (T) ois.readObject(); ois.close(); } catch (Exception e) { e.printStackTrace(); } return newT; } } }