zoukankan      html  css  js  c++  java
  • 原型模式之深浅克隆

    最近入手了一本编程书籍开始研读,主要是听取的公司大佬的建议,自己再回去略一思索,发觉之前的学习方式似乎不怎么健全,一直忽略了书籍的重要性,总是在网络上疯狂搜集零零散散的知识碎片。最近刚好看到关于原型模式这一部分,忽然回想起N久之前貌似就听说过深浅克隆这两个名词,于是将这一章节认认真真的反复研读了几遍(其实也不是很认真,还不怎么习惯看书,感觉精力难以非常集中)。

    书中对原型模式给出的概念是这样的:

    原型模式是指原型实例指定创建对象的种类,并且通过复制这些原型创建新的对象。

    刚看到这里的时候,的确是一脸迷茫,当学完这一节之后,感觉对这句话已经有了一些体会。

    我自己对原型模式概念的理解:

    原型实例就是一个实例对象,相当于一个蓝图,可以将其理解为桌面上的一个文件,通过这个文件我们可以复制出N多个文件,比如你复制了一个txt文件,得到的自然也是一个txt文件。所以说,这个实例对象指定了创建对象的种类,和它自己本身一个类型嘛。

    先上代码:

    //定义浅克隆接口
    public interface Proto {
        Proto clone();
    }

    实现深浅克隆:

    public class ProtoImpl implements Proto,Cloneable,Serializable {
    
        private Integer id;
        private String info;
    
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public String getInfo() {
            return info;
        }
    
        public void setInfo(String info) {
            this.info = info;
        }
    
        @Override
        public Proto clone() {
            ProtoImpl proto = new ProtoImpl();
            proto.setId(this.id);
            proto.setInfo(this.info);
            return proto;
        }
    
        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 Boot {
        public static void main(String[] args) throws IOException, ClassNotFoundException {
            ProtoImpl proto = new ProtoImpl();
            proto.setId(12);
            proto.setInfo("");
            ProtoImpl protoClone = (ProtoImpl) proto.clone();
            //浅克隆
            System.out.println(proto.getInfo() == protoClone.getInfo());
            //深克隆
            protoClone = (ProtoImpl) proto.deepClone();
            System.out.println(proto.getInfo() == protoClone.getInfo());
        }
    }

    以上代码是我根据书中的代码仿照着写的,最终测试结果为浅克隆的info地址相同,而深克隆的info地址不同。

    我个人的理解就是,浅克隆相当于对原对象的一次不严谨的复制,在java中栈保存了基本数据类型的值和引用数据类型的地址,而浅克隆复制的就是栈中的内容,所以,引用数据类型实际上指向的还是原对象的数据。

    而深克隆相当于一次严谨的克隆,上面代码中的深克隆采用的是序列化的方式,所以即便是引用数据类型得到的也是一个全新的数据,而并非指向原对象的数据。

  • 相关阅读:
    javascript的语法作用域你真的懂了吗
    网页的三种布局(固定宽度式,流体式,弹性式)
    css3系列之animation
    跟我学习css3之transition
    函数调用你知道几种方法
    javascript的那些事儿你都懂了吗
    css3的那些高级选择器二
    [转]影响Cache的几个HTTP头信息
    CSS属性合写
    defer 与 async
  • 原文地址:https://www.cnblogs.com/wxdmw/p/13516550.html
Copyright © 2011-2022 走看看