原型模式解决克隆羊问题的应用实例( 二 )


原型模式在框架中源码分析
1) 中原型 bean 的创建,就是原型模式的应用
2)代码分析+Debug 源码
深入讨论-浅拷贝和深拷贝 浅拷贝的介绍
1)对于数据类型是基本数据类型的成员变量,浅拷贝会直接进行值传递,也就是将该属性值复制一份给新的对象 。
2)对于数据类型是引用数据类型的成员变量,比如说成员变量是某个数组、某个类的对象等,那么浅拷贝会进行引用传递,也就是只是将该成员变量的引用值(内存地址)复制一份给新的对象 。因为实际上两个对象的该成员变量都指向同一个实例 。在这种情况下,在一个对象中修改该成员变量会影响到另一个对象的该成员变量值
3)前面我们克隆羊就是浅拷贝
4)浅拷贝是使用默认的 clone()方法来实现
sheep = (Sheep) super.clone();
深拷贝基本介绍
1)复制对象的所有基本数据类型的成员变量值
2)为所有引用数据类型的成员变量申请存储空间,并复制每个引用数据类型成员变量所引用的对象,直到该对象可达的所有对象 。也就是说,对象进行深拷贝要对整个对象(包括对象的引用类型)进行拷贝
3)深拷贝实现方式 1:重写 clone 方法来实现深拷贝
4)深拷贝实现方式 2:通过对象序列化实现深拷贝(推荐)
深拷贝应用实例
1)使用 重写 clone 方法实现深拷贝
2)使用序列化来实现深拷贝
3)代码演示
【原型模式解决克隆羊问题的应用实例】package com.ygp.prototype.deepclone;import java.io.Serializable;public class DeepCloneableTarget implements Serializable, Cloneable {/****/private static final long serialVersionUID = 1L;private String cloneName;private String cloneClass;//构造器public DeepCloneableTarget(String cloneName, String cloneClass) { this.cloneName = cloneName;this.cloneClass = cloneClass;}//因为该类的属性,都是 String ,因此我们这里使用默认的 clone 完成即可@Overrideprotected Object clone() throws CloneNotSupportedException { return super.clone();}}
//...package com.ygp.prototype.deepclone;import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream;import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable;public class DeepProtoType implements Serializable, Cloneable{public String name; //String 属 性public DeepCloneableTarget deepCloneableTarget;// 引用类型public DeepProtoType() { super();}//深拷贝 - 方式 1使用 clone 方法@Overrideprotected Object clone() throws CloneNotSupportedException {Object deep = null;//这里完成对基本数据类型(属性)和 String 的克隆deep = super.clone();//对引用类型的属性,进行单独处理DeepProtoType deepProtoType = (DeepProtoType)deep;deepProtoType.deepCloneableTarget = (DeepCloneableTarget)deepCloneableTarget.clone();// TODO Auto-generated method stub return deepProtoType;}//深拷贝 - 方式 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) {// TODO: handle exception e.printStackTrace();return null;} finally {//关闭流 try {bos.close();oos.close();bis.close();ois.close();} catch (Exception e2) {// TODO: handle exception System.out.println(e2.getMessage());}}}}
//Client.javapackage com.ygp.prototype.deepclone;public class Client {public static void main(String[] args) throws Exception {// TODO Auto-generated method stub DeepProtoType p = new DeepProtoType(); p.name = "宋江";p.deepCloneableTarget = new DeepCloneableTarget("大牛", "小牛");//方式 1完成深拷贝// DeepProtoType p2 = (DeepProtoType) p.clone();//// System.out.println("p.name=" + p.name + "p.deepCloneableTarget=" + p.deepCloneableTarget.hashCode());// System.out.println("p2.name=" + p.name + "p2.deepCloneableTarget=" + p2.deepCloneableTarget.hashCode());//方式 2完成深拷贝DeepProtoType p2 = (DeepProtoType) p.deepClone();System.out.println("p.name=" + p.name + "p.deepCloneableTarget=" + p.deepCloneableTarget.hashCode()); System.out.println("p2.name=" + p.name + "p2.deepCloneableTarget=" + p2.deepCloneableTarget.hashCode());}}