原型设计模式及深拷贝

public class DeepProtoType implements Serializable, Cloneable{
    
    public String name; //String 属性
    public DeepCloneableTarget deepCloneableTarget;// 引用类型
    public DeepProtoType() {
        super();
    }
    
    
    //深拷贝 - 方式 1 使用clone 方法
    @Override
    protected 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());
            }
        }
        
    }
    
}
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完成即可
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
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());
    
    }

}
p.name=宋江p.deepCloneableTarget=1028566121
p2.name=宋江p2.deepCloneableTarget=558638686

总结:

原型设计模式:用原型实例指定创建对象的种类, 并且通过拷贝这些原型创建新的对象。

==注意:==

  1. java中只有值传递,如果是引用类型,传递的是引用,其实也是值传递。
  2. 原型设计模式有深拷贝和浅拷贝,通过Object类的Clone()方法,要使用该方法,必须实现Cloneable接口,想要clone 的属性,不能是final的。
  3. 使用序列化的方式实现深拷贝,必须实现Serializable接口
  4. 值得一提的是,本例中的深拷贝,即DeepCloneableTarget中的两个类型为string类型,拷贝的其实也是引用,但是string类型比较特殊,String类型是不可变的,值存于常量池中,所以我们克隆了两个Sheep时,修改其属性的属性cloneName时,并不会对另一个造成影响。
  5. 使用序列化进行拷贝时,由于是二进制的拷贝,所有构造函数不会被执行。这也是优点,也是缺点,在实际应用中要考虑

转载于:https://www.cnblogs.com/heliusKing/p/11581463.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值