【java開發系列】—— 深克隆和淺克隆

  Java支持咱們對一個對象進行克隆,一般用在裝飾模式和原型模式中。那麼什麼是深克隆,什麼是淺克隆呢。java

  【淺克隆】,一般只是對克隆的實例進行復制,但裏面的其餘子對象,都是共用的。this

  【深克隆】,克隆的時候會複製它的子對象的引用,裏面全部的變量和子對象都是又額外拷貝了一份。spa

  下面的兩個例子能夠很好的說明他們的區別:code

  首先看一下類圖

  Husband類有一個對wife的引用,當進行淺克隆的時,wife變量都會指向同一個Wife;而進行深克隆時,會指向不一樣的Wife。下面進行一下驗證:對象

  【淺克隆】

 1 public Object clone() {  2         Husband husband = null;  3         try{  4             husband = (Husband)super.clone();  5         }catch(CloneNotSupportedException e){  6  e.printStackTrace();  7         }finally{  8             return husband;  9  } 10     }

  【深克隆】

 1 public Object deepClone() throws IOException,ClassNotFoundException {  2         //將對象寫到流裏
 3         ByteArrayOutputStream bos = new ByteArrayOutputStream();  4         ObjectOutputStream oos = new ObjectOutputStream(bos);  5         oos.writeObject(this);  6         //從流裏讀回來
 7         ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());  8         ObjectInputStream ois = new ObjectInputStream(bis);  9         return ois.readObject(); 10     }

  【所有代碼】

 1 package com.xingoo.clone;  2 
 3 import java.io.ByteArrayInputStream;  4 import java.io.ByteArrayOutputStream;  5 import java.io.IOException;  6 import java.io.ObjectInputStream;  7 import java.io.ObjectOutputStream;  8 import java.io.Serializable;  9 import java.util.Date;  10 
 11 class Wife implements Serializable{  12     private String name;  13     private Date birthday;  14     
 15     public Wife(){  16         name = "芙蓉姐姐";  17         birthday = new Date();  18  }  19     public Date getBirthday(){  20         return birthday;  21  }  22     
 23     public String getName() {  24         return name;  25  }  26     public void setName(String name) {  27         this.name = name;  28  }  29 }  30 class Husband implements Cloneable,Serializable{  31     private Wife wife;  32     private Date birthday;  33     
 34     public Husband(){  35         wife = new Wife();  36         birthday = new Date();  37  }  38     
 39     public Wife getWife(){  40         return wife;  41  }  42     
 43     public Date getBirthday(){  44         return birthday;  45  }  46     /**  47  * 淺克隆一個對象  48      */
 49     public Object clone() {  50         Husband husband = null;  51         try{  52             husband = (Husband)super.clone();  53         }catch(CloneNotSupportedException e){  54  e.printStackTrace();  55         }finally{  56             return husband;  57  }  58  }  59     /**  60  * 利用串行化深克隆一個對象,把對象以及它的引用讀到流裏,在寫入其餘的對象  61  * @return  62  * @throws IOException  63  * @throws ClassNotFoundException  64      */
 65     public Object deepClone() throws IOException,ClassNotFoundException {  66         //將對象寫到流裏
 67         ByteArrayOutputStream bos = new ByteArrayOutputStream();  68         ObjectOutputStream oos = new ObjectOutputStream(bos);  69         oos.writeObject(this);  70         //從流裏讀回來
 71         ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());  72         ObjectInputStream ois = new ObjectInputStream(bis);  73         return ois.readObject();  74  }  75 }  76 public class Test {  77     public static void main(String[] args){  78         try{  79             Husband husband = new Husband();  80             System.out.println("husband birthday "+husband.getBirthday().getTime());  81             System.out.println("wife birthday "+husband.getWife().getBirthday().getTime());  82             System.out.println();  83             Husband husband1 = (Husband)husband.clone();  84             System.out.println("husband1 birthday "+husband1.getBirthday().getTime());  85             System.out.println("wife birthday "+husband1.getWife().getBirthday().getTime());  86             System.out.println();  87             System.out.println("是不是同一個husband "+(husband == husband1));  88             System.out.println("是不是同一個wife "+ (husband.getWife() == husband1.getWife()));  89             System.out.println();  90             Husband husband2 = (Husband)husband.deepClone();  91             System.out.println("husband2 birthday "+husband2.getBirthday().getTime());  92             System.out.println("wife birthday "+husband2.getWife().getBirthday().getTime());  93             System.out.println();  94             System.out.println("是不是同一個husband "+(husband == husband2));  95             System.out.println("是不是同一個wife "+ (husband.getWife() == husband2.getWife()));  96         }catch(Exception e){  97  e.printStackTrace();  98  }  99  } 100 }

  【運行結果】

husband birthday 1414247244668 wife birthday 1414247244668 husband1 birthday 1414247244668 wife birthday 1414247244668 是不是同一個husband false 是不是同一個wife true husband2 birthday 1414247244668 wife birthday 1414247244668 是不是同一個husband false 是不是同一個wife false
相關文章
相關標籤/搜索