java 原型模式之深复制与浅复制

转载自:http://blog.csdn.net/liu_yujie2011com/article/details/40510567

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

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

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

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

252235300436698.jpg

 Husband类有一个对wife的引用,当进行浅克隆的时,wife变量都会指向同一个Wife;而进行深克隆时,会指向不同的Wife。下面进行一下验证:

【浅克隆】

public Object clone() {

        Husband husband = null;

        try{

            husband = (Husband)super.clone();

        }catch(CloneNotSupportedException e){

            e.printStackTrace();

        }finally{

            return husband;

        }

    }

【深克隆】

public Object 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 ois.readObject();

    }

【全部代码】

package com.xingoo.clone;


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;


class Wife implements Serializable{

    private String name;

    private Date birthday;

    

    public Wife(){

        name = "芙蓉姐姐";

        birthday = new Date();

    }

    public Date getBirthday(){

        return birthday;

    }

    

    public String getName() {

        return name;

    }

    public void setName(String name) {

        this.name = name;

    }

}

class Husband implements Cloneable,Serializable{

    private Wife wife;

    private Date birthday;

    

    public Husband(){

        wife = new Wife();

        birthday = new Date();

    }

    

    public Wife getWife(){

        return wife;

    }

    

    public Date getBirthday(){

        return birthday;

    }

    /**

     * 浅克隆一个对象

     */

    public Object clone() {

        Husband husband = null;

        try{

            husband = (Husband)super.clone();

        }catch(CloneNotSupportedException e){

            e.printStackTrace();

        }finally{

            return husband;

        }

    }

    /**

     * 利用串行化深克隆一个对象,把对象以及它的引用读到流里,在写入其他的对象

     * @return

     * @throws IOException

     * @throws ClassNotFoundException

     */

    public Object 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 ois.readObject();

    }

}

public class Test {

    public static void main(String[] args){

        try{

            Husband husband = new Husband();

            System.out.println("husband birthday "+husband.getBirthday().getTime());

            System.out.println("wife birthday "+husband.getWife().getBirthday().getTime());

            System.out.println();

            Husband husband1 = (Husband)husband.clone();

            System.out.println("husband1 birthday "+husband1.getBirthday().getTime());

            System.out.println("wife birthday "+husband1.getWife().getBirthday().getTime());

            System.out.println();

            System.out.println("是否是同一个husband "+(husband == husband1));

            System.out.println("是否是同一个wife "+ (husband.getWife() == husband1.getWife()));

            System.out.println();

            Husband husband2 = (Husband)husband.deepClone();

            System.out.println("husband2 birthday "+husband2.getBirthday().getTime());

            System.out.println("wife birthday "+husband2.getWife().getBirthday().getTime());

            System.out.println();

            System.out.println("是否是同一个husband "+(husband == husband2));

            System.out.println("是否是同一个wife "+ (husband.getWife() == husband2.getWife()));

        }catch(Exception e){

            e.printStackTrace();

        }

    }

}

【运行结果】

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,深克隆与浅克隆)