原型模式(Prototype Pattern)

原型模式(Prototype Pattern):用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。(百度百科)

  简单的讲,就是为了创建一个对象,复制一个原有的对象,然后为这个新对象开辟内存空间。

 

在Jdk中提供了复制对象的接口,只需要实现Cloneable接口并重写clone()方法(也可以不实现Cloneable接口,因为Object中默认提供clone()方法:

protected native Object clone() throws CloneNotSupportedException;

),就可以使用clone()方法了。

public class ProtoTypePattern implements Cloneable{
    public ProtoTypePattern() {
        System.out.println("构造函数执行了");
    }

    @Override
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    public static void main(String[] args) {
        ProtoTypePattern protoType = new ProtoTypePattern();
        try {
            ProtoTypePattern clone = (ProtoTypePattern)protoType.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
    }
}

 

如果不实现Cloneable接口,程序会抛出异常:

java.lang.CloneNotSupportedException: com.example.patterns.protoTypePattern.ProtoTypePattern
    at java.lang.Object.clone(Native Method)
    at com.example.patterns.protoTypePattern.ProtoTypePattern.clone(ProtoTypePattern.java:6)
    at com.example.patterns.protoTypePattern.ProtoTypePattern.main(ProtoTypePattern.java:12)

 

使用clone()方法建造的新对象是不执行构造函数的,是从内存中直接开辟一块空间以二进制的方式进行拷贝。构造函数只执行了一次,程序运行结果如下。

Connected to the target VM, address: '127.0.0.1:52677', transport: 'socket'
构造函数执行了
Disconnected from the target VM, address: '127.0.0.1:52677', transport: 'socket'

以上就是原型模式的实现。

 

但还不够,因为还涉及到一个浅克隆和深克隆的概念。

Object默认的clone()实现方式是浅克隆,一个对象中只有基本数据类型和String类型(String类型不可更改)会克隆,其他的引用对象或数组引用则会指向原有对象。当一处修改对象时,两边都会变化。

解决办法是让克隆对象中的引用对象实现Cloneable接口,将引用对象的克隆值作为克隆对象新的引用对象。

 

还有一个解决办法是使用串行化,使用字节数组流将对象写入再读出来。这样做必须写入的对象及引用的对象都是可串行的,否则就需要将不可串行化的对象用transient修饰。

public Object deepClone()    
{    
//将对象写到流里    
ByteArrayOutoutStream bo=new ByteArrayOutputStream();    
ObjectOutputStream oo=new ObjectOutputStream(bo);    
oo.writeObject(this);    
//从流里读出来    
ByteArrayInputStream bi=new ByteArrayInputStream(bo.toByteArray());    
ObjectInputStream oi=new ObjectInputStream(bi);    
return(oi.readObject());    
}  

 

转载于:https://www.cnblogs.com/handler4J/p/10136607.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值