设计模式--Java原型模式个人学习记录

学习自《JAVA与模式》之原型模式,
(二十三)原型模式详解(clone方法源码的简单剖析)

代码见zhj_design_patterns的prototype_pattern

什么是原型模式?
属于对象的创建模式,我理解的就是复制一个原型对象,创建出很多个同类型的对象。

就是.clone()

Java对原型模式的支持:
Object类提供了一个方法 clone,而Java中所有的类只要实现Cloneable接口(不继承的话会报CloneNotSupportedException),就可以重写clone方法进行对象拷贝,主要是重写一下clone方法

举个例子:
在这里插入图片描述
运行一下可以看出,clone方法将prototype1复制了一个,值都一样,但是并没有执行构造方法,因为构造函数中的那句话没有被打印。

原型模式的应用场景:
1.创建比较复杂的对象时,可以使用原型模式快捷的创建对象(所以在速度上比使用new的方式创建对象要快)
2.在运行过程中不知道对象的具体类型,可以使用原型模式创建一个相同类型的对象。
3.可以基于原型,快速的创建一个对象,而无需知道创建的细节。

从虚拟机源码可以看出:将clone方法想象成内存块的复制操作,它的速度比一般的创建对象操作要快。

原型模式的缺点

1.原型模式最主要的缺点是每一个类都必须配备一个克隆方法。配备克隆方法需要对类的功能进行通盘考虑,这对于全新的类来说不是很难,而对于已经有的类不一定很容易,特别是当一个类引用不支持序列化的间接对象,或者引用含有循环结构的时候。
2.需要额外的代码量

不过实际当中我们使用原型模式时,也可以写一个基类实现Cloneable接口重写clone方法,然后让需要具有拷贝功能的子类继承自该类,这是一种节省代码量的常用方式。像上面的例子一样,如果一个类继承自Prototype,则会自动具有拷贝功能。

上面的例子是一个浅克隆,因为在复制对象内部的引用类型的属性时,它只拷贝引用。

克隆满足的条件

clone()方法将对象复制了一份并返还给调用者。所谓“复制”的含义与clone()方法是怎么实现的。一般而言,clone()方法满足以下的描述:

(1)对任何的对象x,都有:x.clone()!=x。换言之,克隆对象与原对象不是同一个对象。

(2)对任何的对象x,都有:x.clone().getClass() == x.getClass(),换言之,克隆对象与原对象的类型一样。

(3)如果对象x的equals()方法定义其恰当的话,那么x.clone().equals(x)应当成立的。

在JAVA语言的API中,凡是提供了clone()方法的类,都满足上面的这些条件。JAVA语言的设计师在设计自己的clone()方法时,也应当遵守着三个条件。一般来说,上面的三个条件中的前两个是必需的,而第三个是可选的。
浅拷贝与深拷贝的区别

浅拷贝:
只复制按值传递的数据(基本数据类型,String),而不复制他所引用的对象,也就是说对其他对象的引用都仍然指向原来的对象。

深拷贝:
深度克隆把要复制的对象所引用的对象都复制了一遍, 深度克隆要深入到多少层,是一个不易确定的问题。在决定以深度克隆的方式复制一个对象的时候,必须决定对间接复制的对象时采取浅度克隆还是继续采用深度克隆。因此,在采取深度克隆时,需要决定多深才算深。此外,在深度克隆的过程中,很可能会出现循环引用的问题,必须小心处理。

浅克隆中引用的地址是一样的,而深克隆每个都不一样

深度克隆有两种方法:
1.序列化实现深度克隆:
把对象写到流里的过程是序列化(Serialization)过程;而把对象从流中读出来的过程则叫反序列化(Deserialization)过程。应当指出的是,写到流里的是对象的一个拷贝,而原对象仍然存在于JVM里面。

2.复制每一个所引用的对象,(对每个引用进行clone(),不知道这算是一种么)

序列化深克隆:

在Java语言里深度克隆一个对象,常常可以先使对象实现Serializable接口,然后把对象(实际上只是对象的拷贝)写到一个流里(序列化),再从流里读回来(反序列化),便可以重建对象。
  
  在这里插入图片描述
  首先,这个对象要实现java.io.Serializable接口,保证该对象是可以序列化的,而且该对象内部所有引用的对象都是可序列化的(实现java.io.Serializable),否则,就需要仔细考察那些不可序列化的对象可否设成transient,从而将之排除在复制过程之外。

有一些对象,比如线程(Thread)对象或Socket对象,是不能简单复制或共享的。不管是使用浅度克隆还是深度克隆,只要涉及这样的间接对象,就必须把间接对象设成transient而不予复制;或者由程序自行创建出相当的同种对象,权且当做复制件使用。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值