java中实现原型模式的两种方法(浅拷贝和深拷贝)

java中原型模式的两种方法
浅拷贝:
    protected Object clone() throws CloneNotSupportedException {
return super.clone();//浅拷贝
    }

从Object中继承过来的clone默认实现的是浅拷贝.

深拷贝
方式1:

使用clone方法

    protected Object clone() throws CloneNotSupportedException {
        Sheep sheep = null;
Sheep sheep= super.clone();//既然默认继承的可以做到浅拷贝,那么就先让其浅拷贝,减少后面手动赋值的代码量.
        //然后进行深拷贝;
        Sheep sheep1= Sheep(sheep);
sheep1.friend= (One) friend.clone();//让其再次使用引用属性的clone();

        return sheep1;
    }

此处必须注意的是:对于要拷贝的这个类来说,必须实现cloneable接口;

另外,更更重要的是:将该对象引用的其他对象clone一份,说明被引用的对象也要实现Cloneable接口.但是实现了之后如果这个被引用的对象中还有其他的对象,那么又要进行深拷贝,如此反复循环下去.

第二种方式:
     public Object deepClone()
     {
         ByteArrayInputStream bis=null;
         ByteArrayOutputStream bos=null;
         ObjectInputStream ois=null;
         ObjectOutputStream oos=null;
         try{
//             序列化
         
             bos=new ByteArrayOutputStream();
             oos=new ObjectOutputStream(bos);
             oos.writeObject(this);//当前这个对象以对象流的方式输出
//             反序列化
             bis=new ByteArrayInputStream(bos.toByteArray());
             ois=new ObjectInputStream(bis);
             Object o = ois.readObject();
          return ois;
         }    
          catch (IOException | ClassNotFoundException e) {
             e.printStackTrace();
              return null;
         }finally{
              //关闭所有的流;
              bos.close();
              bis.close();
              oos.close();
              ois.close();
          }
     
}

public byte[] toByteArray() 创建一个新分配的字节数组。数组的大小和当前输出流的大小,内容是当前输出流的拷贝。

ByteArrayOutputStream:字节数组输出流在内存中创建一个字节数组缓冲区,所有发送到输出流的数据保存在该字节数组缓冲区中。创建字节数组输出流对象有以下几种方式。

下面的构造方法创建一个32字节(默认大小)的缓冲区。

OutputStream bOut = new ByteArrayOutputStream();

另一个构造方法创建一个大小为 a 字节的缓冲区。

OutputStream bOut = new ByteArrayOutputStream(int a)//创建一个大小为a字节的缓冲区;

成功创建字节数组输出流对象后,可以参见以下列表中的方法,对流进行写操作或其他操作。

序号方法描述
1public void reset() 将此字节数组输出流的 count 字段重置为零,从而丢弃输出流中目前已累积的所有数据输出。
2public byte[] toByteArray() 创建一个新分配的字节数组。数组的大小和当前输出流的大小,内容是当前输出流的拷贝。
3public String toString() 将缓冲区的内容转换为字符串,根据平台的默认字符编码将字节转换成字符。
4public void write(int w) 将指定的字节写入此字节数组输出流。
5public void write(byte []b, int off, int len) 将指定字节数组中从偏移量 off 开始的 len 个字节写入此字节数组输出流。
6public void writeTo(OutputStream outSt) 将此字节数组输出流的全部内容写入到指定的输出流参数中。

结论

创建新的对象比较复杂时,可以利用原型模式简化对象的创建过程,同时也能够提高效率

不用重新初始化对象,而是动态的活的对象运行时的状态

如果原始对象发生变化,变化之后克隆的对象也会发生相应的变化,无序修改代码;

在实现深克隆的时候可能需要比较复杂的代码.

缺点:需要为每一个类配备一个克隆方法,这对全新的类来说,但对已有的类进行改造时,需要修改其源代码,违背了OCP原则(开闭原则);

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值