所谓的原型模式,就是用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
1.首先需要了解java的clone技术
我理解的很简单,无非是把一个对象进行复制粘贴。那么,来看一下JAVA语言中是如何来实现的这个步骤的。我们依次需要知道以下这些事。
1.Object对象中有一个clone()方法。而且是protected。
2.继承于Object的类一般都可以实现这个方法(有特殊的,比如StringBuffer等,官方定的,不去研究它)。
3.想被clone的对象需要实现接口Cloneable。如果此对象的类不能实现接口Cloneable,则会抛出CloneNotSupportedExcetion。
4.所有的数组都被视为实现接口Cloneable。
5.clone分为浅clone(又称影子clone)和深clone。
6.Object类本身不实现接口Cloneable,所以在类为Object的对象上调用clone方法,将会导致在运行时抛出异常。
关键所在深克隆和浅克隆,那到底他们之间有什么区别呢?
首先看一下例子:
public abstract class CloneClass implements Cloneable {
public int aInt;
public Object clone() {
CloneClass o = null;
try {
o = (CloneClass) super.clone();
} catch (CloneNotSupportedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return o;
}
}
public class UnCloneA {
private int i;
public UnCloneA(int ii) {
i = ii;
}
public void doublevalue() {
i *= 2;
}
public String toString() {
return Integer.toString(i);
}
}
public class CloneB implements Cloneable {
public int aInt;
public UnCloneA unCloneA = new UnCloneA(111);
public Object clone() {
CloneB o = null;
try {
o = (CloneB) super.clone();
} catch (CloneNotSupportedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return o;
}
}
public class Test {
public static void main(String args[]) {
CloneB b1 = new CloneB();
b1.aInt = 11;
System.out.println("before clone,b1.aInt = " + b1.aInt);
System.out.println("before clone,b1.unCA = " + b1.unCloneA);
CloneB b2 = (CloneB) b1.clone();
b2.aInt = 22;
b2.unCloneA.doublevalue();
System.out.println("=================================");
System.out.println("after clone,b1.aInt = " + b1.aInt);
System.out.println("after clone,b1.unCA = " + b1.unCloneA);
System.out.println("=================================");
System.out.println("after clone,b2.aInt = " + b2.aInt);
System.out.println("after clone,b2.unCA = " + b2.unCloneA);
}
}
输出结果:
before clone,b1.aInt = 11
before clone,b1.unCA = 111
=================================
after clone,b1.aInt = 11
after clone,b1.unCA = 222
=================================
after clone,b2.aInt = 22
after clone,b2.unCA = 222
可见,当执行clone这个动作的时候,系统首先开辟一个和它一样的空间。然后分别对其内容进行复制。复制过程中,如果是基本类型,没什么说的,直接把值复制过来。如果不是基本类型,复制的则是该类型对象的引用。
这样的clone就是所谓的浅clone。那很显然,如果上面复制的过程中,对于非基本类型实现的不是一个引用复制,而是创建一个新的一样的对象(其实也是一个clone步骤),那么就是所谓的深clone。对于深度克隆只不过是clone的一种扩展,还有N深clone等等。对于这些,和我们要研究的原型模式没有多少关系。
1、浅克隆:
a. 提供一个类作为克隆的原型,该类实现了Clonable接口
b. 在该类中覆盖Object类的clone()方法,采用super.clone()方法完成克隆
c. 在外部使用场合先产生一个原型对象,然后调用其clone()方法产生克隆对象
2、深克隆:
a. 提供一个类作为克隆的原型,该类实现了Serializable接口
b. 在该类中覆盖Object类的clone()方法,采用序列化的方法完成克隆(对象流的读写)
c.在外部使用场合先产生一个原型对象,然后调用其clone()方法产生克隆对象
二、Prototype模式与深、浅克隆:
使用Object.clone()方法进行的克隆是“浅克隆”-被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象。浅克隆的步骤如下:
①为了获取对象的一份拷贝,我们可以利用Object类的clone()方法。
②在派生类中覆盖基类的clone()方法,并声明为public。
③在派生类的clone()方法中,调用super.clone()。
④在派生类中实现Cloneable接口。
为什么我们在派生类中覆盖Object的clone()方法时,一定要调用super.clone()呢?在运行时刻,Object中的clone()要识别出你要复制的是哪一个对象,然后为此对象分配空间,并进行对象的复制,将原始对象的内容一一复制到新对象的存储空间中。
要实现“深克隆”-被复制对象的所有变量都含有与原来的对象相同的值,除去那些引用其他对象的变量。那些引用其他对象的变量将指向被复制过的新对象,而不再是原有的那些被引用的对象。换言之,深复制把要复制的对象所引用的对象都复制了一遍。
深克隆需要使用Java中提供的对象串行化功能-即把要复制的对象写入到一个缓冲流,然后通过输入流读入,完成对象的复制
下面是深克隆与浅克隆的代码
public class SuperStar implements Cloneable, Serializable {
public String name;
public int height;
public Skill mySkill;
public Object clone() {
Object o = null;
try {
o = super.clone();
} catch (CloneNotSupportedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return o;
}
public Object deepClone() throws Exception {
Object o = null;
try {
ByteArrayOutputStream bos = new ByteArrayOutputStream(); // (ByteArrayOutputStream)此类实现了一个输出流,其中
// 的数据被写入一个字节数组。缓冲区会随着数据的不断写入而自动增长。
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(this); // 通过Serialization机制将自身写入该缓冲区
// 找到刚才开辟的缓冲区准备读取
ByteArrayInputStream bis = new ByteArrayInputStream(bos
.toByteArray()); //
ObjectInputStream ois = new ObjectInputStream(bis);
// 将刚才写入的内容读入一个新的对象
o = ois.readObject();
bos.close();
oos.close();
bis.close();
ois.close();
} catch (Exception e) {
e.printStackTrace();
}
return o;
}
}
public class Skill implements Serializable{
public int strength;
public int jumping;
}
public class Test {
public static void main(String args[]) throws Exception{
SuperStar s1=new SuperStar();
s1.name="姚明";
s1.height=226;
s1.mySkill=new Skill();
s1.mySkill.jumping=50;
s1.mySkill.strength=20;
System.out.println(s1.name+" " + s1.height +" "+s1.mySkill.jumping);
SuperStar s2=(SuperStar) s1.clone();
// SuperStar s2=(SuperStar) s1.deepClone();
s2.name="潘长江";
s2.height=100;
s2.mySkill.jumping=10;
s2.mySkill.strength=5;
System.out.println(s2.name+" " + s2.height+" " +s2.mySkill.jumping);
System.out.println(s1.name+" " + s1.height +" "+s1.mySkill.jumping);
}
}
浅克隆 结果
姚明 226 50
潘长江 100 10
姚明 226 10
深克隆 结果
姚明 226 50
潘长江 100 10
姚明 226 50
JAVA中的clone方法,其实现是native的。这也就意味着它的执行效率是远高于new一个新对象的。所以,当需要生成大量相似对象的时候,可以考虑下应用clone,也就是原形模式。
分享到:
相关推荐
scratch少儿编程逻辑思维游戏源码-工厂逃生.zip
房地产 -辉盛阁项目介绍.pptx
少儿编程scratch项目源代码文件案例素材-新拉力赛.zip
scratch少儿编程逻辑思维游戏源码-混乱弹球.zip
scratch少儿编程逻辑思维游戏源码-过马路.zip
少儿编程scratch项目源代码文件案例素材-侠盗地牢冒险.zip
少儿编程scratch项目源代码文件案例素材-我的领土.zip
scratch少儿编程逻辑思维游戏源码-机器人闯关.zip
少儿编程scratch项目源代码文件案例素材-天空中的英雄.zip
少儿编程scratch项目源代码文件案例素材-突击尖峰.zip
“即刻青旅”前景广阔,随着青年旅舍行业快速发展,2030年市场规模预计达650亿。创作旨在为年轻旅行者打造专属平台,填补国内专门青旅预定空白。融合微信小程序、Spring Boot等技术,实现青旅查询预定、订单管理、活动职位查看及社区分享等功能。 后端框架: 基于Java的SpringBoot快速开发框架 借助Mybatis-plus构建ORM模型进行数据库操作 第三方API:高德地图、腾讯地图
少儿编程scratch项目源代码文件案例素材-像素猫3.zip
内容概要:本文是一份详细的10bit 50MHz SAR ADC学习指南,旨在帮助新手掌握从基础理论到实际电路设计的全过程。文中详细介绍了Cadence仿真工具的应用以及SMIC 40nm工艺库的具体使用方法。重点讲解了栅压自举开关、CDAC(电荷再分配模数转换器)、比较器和SAR逻辑等核心模块的设计原理和技术要点。此外,还提供了测试电路的构建方法及其性能评估手段,如INL/DNL曲线绘制。最后提到了更高性能TI ADC的扩展接口,为后续深入研究打下基础。 适合人群:对模拟集成电路设计感兴趣的电子工程专业学生或刚入行的研发人员。 使用场景及目标:适用于希望深入了解SAR ADC架构、提高自身硬件设计能力的学习者;目标是在实践中掌握关键技术和优化技巧,能够独立完成类似项目的开发。 其他说明:文章不仅提供理论知识,还包括大量实用的操作提示和常见错误避免建议,有助于读者快速上手并减少试错成本。
scratch少儿编程逻辑思维游戏源码-防空火力 3D.zip
智慧消防安全与应急管理是现代城市安全管理的重要组成部分,随着城市化进程的加速,传统消防安全管理面临着诸多挑战,如消防安全责任制度落实不到位、消防设施日常管理不足、消防警力不足等。这些问题不仅制约了消防安全管理水平的提升,也给城市的安全运行带来了潜在风险。然而,物联网和智慧城市技术的快速发展为解决这些问题提供了新的思路和方法。智慧消防作为物联网和智慧城市技术结合的创新产物,正在成为社会消防安全管理的新趋势。 智慧消防的核心在于通过技术创新实现消防安全管理的智能化和自动化。其主要应用包括物联网消防安全监管平台、城市消防远程监控系统、智慧消防平台等,这些系统利用先进的技术手段,如GPS、GSM、GIS等,实现了对消防设施的实时监控、智能巡检和精准定位。例如,单兵定位方案通过信标点定位和微惯导加蓝牙辅助定位技术,能够精确掌握消防人员的位置信息,从而提高救援效率和安全性。智慧消防不仅提升了消防设施的管理质量,还优化了社会消防安全管理资源的配置,降低了管理成本。此外,智慧消防的应用还弥补了传统消防安全管理中数据处理方式落后、值班制度执行不彻底等问题,赋予了建筑消防设施智能化、自动化的能力。 尽管智慧消防技术在社会消防安全管理工作中的应用已经展现出巨大的潜力和优势,但目前仍处于实践探索阶段。相关职能部门和研究企业需要加大研究开发力度,进一步完善系统的功能与实效性。智慧消防的发展既面临风险,也充满机遇。当前,社会消防安全管理工作中仍存在制度执行不彻底、消防设施日常维护不到位等问题,而智慧消防理念与技术的应用可以有效弥补这些弊端,提高消防安全管理的自动化与智能化水平。随着智慧城市理念的不断发展和实践,智慧消防将成为推动社会消防安全管理工作与城市化进程同步发展的关键力量。
scratch少儿编程逻辑思维游戏源码-节奏空间.zip
scratch少儿编程逻辑思维游戏源码-黑白色.zip
scratch少儿编程逻辑思维游戏源码-简单射击游戏.zip
少儿编程scratch项目源代码文件案例素材-头头连连看.zip
少儿编程scratch项目源代码文件案例素材-移动小球.zip