原型模式之深浅克隆
最近入手了一本编程书籍开始研读,主要是听取的公司大佬的建议,自己再回去略一思索,发觉之前的学习方式似乎不怎么健全,一直忽略了书籍的重要性,总是在网络上疯狂搜集零零散散的知识碎片。最近刚好看到关于原型模式这一部分,忽然回想起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中栈保存了基本数据类型的值和引用数据类型的地址,而浅克隆复制的就是栈中的内容,所以,引用数据类型实际上指向的还是原对象的数据。
而深克隆相当于一次严谨的克隆,上面代码中的深克隆采用的是序列化的方式,所以即便是引用数据类型得到的也是一个全新的数据,而并非指向原对象的数据。