首页 > 代码库 > 【java开发系列】—— 深克隆和浅克隆

【java开发系列】—— 深克隆和浅克隆

  Java支持我们对一个对象进行克隆,通常用在装饰模式和原型模式中。那么什么是深克隆,什么是浅克隆呢。

  【浅克隆】,通常只是对克隆的实例进行复制,但里面的其他子对象,都是共用的。

  【深克隆】,克隆的时候会复制它的子对象的引用,里面所有的变量和子对象都是又额外拷贝了一份。

  下面的两个例子可以很好的说明他们的区别:

  首先看一下类图

  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 1414247244668wife birthday 1414247244668husband1 birthday 1414247244668wife birthday 1414247244668是否是同一个husband false是否是同一个wife truehusband2 birthday 1414247244668wife birthday 1414247244668是否是同一个husband false是否是同一个wife false

 

【java开发系列】—— 深克隆和浅克隆