在Java中,對象的復制可分為深拷貝和淺拷貝兩種方式。深拷貝和淺拷貝的主要區別在于復制的對象的成員的復制方式是不同的。
淺拷貝是指僅復制這個對象的引用,而不是對象本身。也就是說,淺拷貝僅僅是復制了一個指針,讓多個對象指向同一個內存地址,這樣,如果其中一個對象改變了這個地址所在的數據,那么其它對象也會受到影響。
public class ShallowCopyExample { // 假設這里是一個復雜的對象 private Object data; public void setData(Object data) { this.data = data; } public Object getData() { return data; } // 淺拷貝 public ShallowCopyExample shallowCopy() throws CloneNotSupportedException { return (ShallowCopyExample) super.clone(); } }
上述的ShallowCopyExample類中的shallowCopy()方法使用了Object類的clone()方法來實現淺拷貝,但由于默認的Object.clone()方法只是拷貝了本對象的基本數據類型(包括數組的基本類型)及其引用地址,沒有拷貝對象的狀態,因此需要重寫clone()方法,這就需要實現Cloneable接口來告訴Java虛擬機這個類是可以被克隆的。
深拷貝是指對一個對象的復制,除了原對象的所有成員變量都是屬于該對象的,而新的對象將會完全復制原來對象中所有成員變量的值,而不是簡單的拷貝原對象的引用。
public class DeepCopyExample implements Serializable { // 假設這里是一個復雜的對象 private Object data; public void setData(Object data) { this.data = data; } public Object getData() { return data; } // 深拷貝 public DeepCopyExample deepCopy() throws IOException, ClassNotFoundException { // 序列化 ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos); oos.writeObject(this); // 反序列化 ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bis); return (DeepCopyExample) ois.readObject(); } }
上述的DeepCopyExample類中的deepCopy()方法使用了Java中的Serializable接口來實現深拷貝,這樣可以將對象序列化后再反序列化,這樣就能完整地復制一個新的對象了。