java中的複製方法有兩種:
淺複製和深複製
淺度複製
只負責複製按值傳遞的資料(比如基礎資料型別 (Elementary Data Type)、String類型),而不複製它所引用的對象,換言之,所有的對其他對象的引用都仍然指向原來的對象。 深度複製
除了淺度複製要複製的值外,還負責複製參考型別的資料。那些引用其他對象的變數將指向被複製過的新對象,而不再是原有的那些被引用的對象。換言之,深度複製把要複製的對象所引用的對象都複製了一遍,而這種對被引用到的對象的複製叫做間接複製。
深度複製要深入到多少層,是一個不易確定的問題。在決定以深度複製的方式複製一個對象的時候,必須決定對間接複製的對象時採取淺度複製還是繼續採用深度複製。因此,在採取深度複製時,需要決定多深才算深。此外,在深度複製的過程中,很可能會出現循環參考的問題,必須小心處理。 利用序列化實現深度複製
把對象寫到流裡的過程是序列化(Serialization)過程;而把對象從流中讀出來的過程則叫還原序列化(Deserialization)過程。應當指出的是,寫到流裡的是對象的一個拷貝,而原對象仍然存在於JVM裡面。
在Java語言裡深度複製一個對象,常常可以先使對象實現Serializable介面,然後把對象(實際上只是對象的拷貝)寫到一個流裡(序列化),再從流裡讀回來(還原序列化),便可以重建對象。
package com.lkx.sjms.protory;import java.io.Serializable;public class GoldRingedStaff implements Serializable{private float height = 100.0f; private float diameter = 10.0f; /** * 增長行為,每次調用長度和半徑增加一倍 */ public void grow(){ this.diameter *= 2; this.height *= 2; } /** * 縮小行為,每次調用長度和半徑減少一半 */ public void shrink(){ this.diameter /= 2; this.height /= 2; }}
package com.lkx.sjms.protory;import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.io.Serializable;import java.util.Date;public class Mokey implements Cloneable,Serializable{private int height;private int weight;private Date brithDay;private GoldRingedStaff staff;public Mokey(){this.brithDay= new Date();staff = new GoldRingedStaff();}/*** * 淺複製 */public Mokey clone(){Mokey temp = null;try{temp = (Mokey)super.clone();}catch (Exception e) {e.printStackTrace();}finally{return temp;}}/*** * 深度複製 * @return * @throws IOException * @throws ClassNotFoundException */public Mokey deepClone() 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 (Mokey)ois.readObject();}public int getHeight() {return height;}public void setHeight(int height) {this.height = height;}public int getWeight() {return weight;}public void setWeight(int weight) {this.weight = weight;}public Date getBrithDay() {return brithDay;}public void setBrithDay(Date brithDay) {this.brithDay = brithDay;}public GoldRingedStaff getStaff() {return staff;}public void setStaff(GoldRingedStaff staff) {this.staff = staff;}}
package com.lkx.sjms.protory;import java.io.IOException;public class ProtoryTest {private Mokey mokey = new Mokey();public static void main(String[] args) throws ClassNotFoundException, IOException {ProtoryTest protory = new ProtoryTest();protory.change();}public void change() throws ClassNotFoundException, IOException{Mokey copmokey = mokey.deepClone();System.out.println("大聖本尊的生日"+mokey.getBrithDay());System.out.println("複製大聖的生日"+copmokey.getBrithDay());System.out.println("複製的大聖和大聖本尊是否為同一個對象"+(mokey==copmokey));System.out.println("複製大聖的金箍棒和大聖本尊的金箍棒是否為同一個對象"+(mokey.getStaff()==copmokey.getStaff()));}}