首页 > 其他 > 详细

2.how

时间:2020-02-15 16:07:21      阅读:84      评论:0      收藏:0      [点我收藏+]

@Data
public class PrototypeSheep implements Cloneable{

    private String name;
    private Integer age;
    private String color;

    private PrototypeSheep friend;
    public PrototypeSheep() {
    }

    public PrototypeSheep(String name, Integer age, String color) {
        this.name = name;
        this.age = age;
        this.color = color;
    }


    @Override
    public String toString() {
        return "PrototypeSheep{" +
                "name=‘" + name + ‘\‘‘ +
                ", age=" + age +
                ", color=‘" + color + ‘\‘‘ +
                ", friend=" + friend +
                ‘}‘;
    }

    /**
     * 克隆该实例,采用默认的clone方法来完成
     * @return
     */
    @Override
    protected Object clone() {
        PrototypeSheep sheep = null;

        try {
            sheep = (PrototypeSheep) super.clone();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return sheep;
    }
}
测试
public class client {
    public static void main(String[] args) {
        PrototypeSheep sheep = new PrototypeSheep("tom", 1, "白色");
        PrototypeSheep friend = new PrototypeSheep("jack", 2, "黑色");
        sheep.setFriend(friend);

        PrototypeSheep sheep1 = (PrototypeSheep) sheep.clone();
        PrototypeSheep sheep2 = (PrototypeSheep) sheep.clone();
        PrototypeSheep sheep3 = (PrototypeSheep) sheep.clone();
        sheep1.getFriend().setColor("蓝色");

        System.out.println("sheep = " + sheep   +" sheep.friend="+ sheep.getFriend().hashCode());
        System.out.println("sheep1 = " + sheep1 +" sheep1.friend="+ sheep1.getFriend().hashCode());
        System.out.println("sheep2 = " + sheep2 +" sheep2.friend="+ sheep2.getFriend().hashCode());
        System.out.println("sheep3 = " + sheep3 +" sheep3.friend="+ sheep3.getFriend().hashCode());

    }
}
技术分享图片

对于默认实现的原型,对于引用类型的属性,克隆的对象依然保持的是原对象的指针的指向
每个克隆出的对象的其引用属性地址的hashCode是一样的

于是就引出了深克隆(深拷贝)

技术分享图片
技术分享图片



public class DeepCloneableTarget implements Serializable,Cloneable {
    private static final long serialVersionUID = -5967898240709529077L;

    private String cloneName;
    private String cloneClass;


    public DeepCloneableTarget() {
    }

    public DeepCloneableTarget(String cloneName, String cloneClass) {
        this.cloneName = cloneName;
        this.cloneClass = cloneClass;
    }

    public String getCloneName() {
        return cloneName;
    }

    public void setCloneName(String cloneName) {
        this.cloneName = cloneName;
    }

    public String getCloneClass() {
        return cloneClass;
    }

    public void setCloneClass(String cloneClass) {
        this.cloneClass = cloneClass;
    }


    /**
     * 该类的属性,都是String,因此使用默认的clone完成即可
     * @return
     * @throws CloneNotSupportedException
     */
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}


package cn.xxm.gof23.creational.prototype.deepclone;

import java.io.*;

/**
 * @program: gof23
 * @link: 55864455@qq.com
 * @author: Mr.Xxm
 * @create: 2020-02-15 14:46
 **/
public class DeepProtoType implements Serializable,Cloneable {

    private static final long serialVersionUID = 5180880872263164878L;

    private String name;
    private DeepCloneableTarget deepCloneableTarget; // 引用类型

    public DeepProtoType() {
    }


    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public DeepCloneableTarget getDeepCloneableTarget() {
        return deepCloneableTarget;
    }

    public void setDeepCloneableTarget(DeepCloneableTarget deepCloneableTarget) {
        this.deepCloneableTarget = deepCloneableTarget;
    }


    @Override
    public String toString() {
        return "DeepProtoType{" +
                "name=‘" + name + ‘\‘‘ +
                ", deepCloneableTarget=" + deepCloneableTarget +
                ‘}‘;
    }

    /**
     * 深拷贝-方式1 使用clone方法
     * @return
     * @throws CloneNotSupportedException
     */
    @Override
    protected Object clone() throws CloneNotSupportedException {
        Object deep = null;

        // 这里完成对基本数据类型(属性)和String的克隆
        deep = super.clone();

        // 对引用类型的属性,进行单独处理
        DeepProtoType deepProtoType = (DeepProtoType) deep;
        DeepCloneableTarget deepCloneableTarget = (DeepCloneableTarget) deepProtoType.getDeepCloneableTarget().clone();
        deepProtoType.setDeepCloneableTarget(deepCloneableTarget);

        return deep;
    }


    // 深拷贝 - 方式2  通过对象的序列化实现(推荐)
    public Object deepClone(){
        // 创建流对象
        ByteArrayOutputStream bos = null;
        ObjectOutputStream oos = null;

        ByteArrayInputStream bis = null;
        ObjectInputStream ois = null;

        try {
            // 序列化操作
            bos = new ByteArrayOutputStream();
            oos = new ObjectOutputStream(bos);
            oos.writeObject(this); // 当前这个对象以对象流的方式输出

            // 反序列化
            bis = new ByteArrayInputStream(bos.toByteArray());
            ois = new ObjectInputStream(bis);

            DeepProtoType copyObj = (DeepProtoType)ois.readObject();
            return copyObj;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }finally {
            try {
                bos.close();
                oos.close();
                bis.close();
                ois.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }



}


/**
 * @program: gof23
 * @link: 55864455@qq.com
 * @author: Mr.Xxm
 * @create: 2020-02-15 15:04
 **/
public class Client {
    public static void main(String[] args) throws CloneNotSupportedException {
        DeepProtoType p = new DeepProtoType();
        p.setName("松江");
        p.setDeepCloneableTarget(new DeepCloneableTarget("大牛","小妞"));

        // 方式1 完成深拷贝
        //DeepProtoType  p2 = (DeepProtoType) p.clone();

        // 方式2 完成深拷贝
        DeepProtoType  p2 = (DeepProtoType) p.deepClone();

        System.out.println("p.name = " + p.getName() +" p.getDeepCloneableTarget="+p.getDeepCloneableTarget().hashCode());
        System.out.println("p2.name = " + p2.getName() +" p2.getDeepCloneableTarget="+p2.getDeepCloneableTarget().hashCode());
    }
}


技术分享图片

2.how

原文:https://www.cnblogs.com/xxm520/p/d5752d9756edd510a48dec20ba613761.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!