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