【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 1414247244668

wife birthday 1414247244668



husband1 birthday 1414247244668

wife birthday 1414247244668

是否是同一个husband false

是否是同一个wife true



husband2 birthday 1414247244668

wife birthday 1414247244668

是否是同一个husband false

是否是同一个wife false

 

你可能感兴趣的:(java开发)