原型模式-2
来源:互联网 发布:手工客软件 编辑:程序博客网 时间:2024/05/29 18:44
原型模式的核心是一个clone方法,通过这个方法进行对象的复制,在java中,提供了一个Cloneable接口来标示这个对象是可复制的,在本例中DayLife对象就实现了Cloneable接口。为什么说是“标示”呢?查看Clonealbe类源码,会发现,Cloneable接口中一个方法都没有,这个接口的作用就是一个标示,只有实现该接口的对象才有可能被复制!如何从“有可能被复制”变成“可以被复制”呢,方法就是覆盖超类Object的clone()方法!
1.克隆对象时对象的构造方法不执行,这个我们已经在原型模式-1中测试过了。
2.这里我们主要测试另外一个问题:浅复制和深复制
创建一个测试类:
看,说明model和它的复制对象model2已经没有联系了。
1.克隆对象时对象的构造方法不执行,这个我们已经在原型模式-1中测试过了。
2.这里我们主要测试另外一个问题:浅复制和深复制
创建一个Model类,该类实现Cloneable接口。
package com.demo.prototype.clonetest;import java.util.ArrayList;public class Model implements Cloneable {private String te = ""; private ArrayList<String> nameList= new ArrayList<String>(); public ArrayList<String> getNameList() {return nameList;}public String getTe() {return te;}public void putTe(String str) { te = str;}//添加内容public void add(String str){this.nameList.add(str);}//Clone方法@SuppressWarnings("unchecked")@Overridepublic Model clone(){try {Model model = (Model)super.clone();return model;} catch (CloneNotSupportedException e) {e.printStackTrace();}return null;}}
创建一个测试类:
package com.demo.prototype.clonetest;public class TestMain {public static void main(String args[]){//创建modle对象Model model = new Model();//设置model对象内容model.add("aa");model.add("bb");model.putTe("abc123");//打印显示model中namelist内容System.out.println(model.getNameList());System.out.println(model.getTe());//将model内容克隆给model2Model model2 = model.clone();model2.add("cc");model2.putTe("def456");//打印显示model2中namelist内容System.out.println(model2.getNameList());System.out.println(model2.getTe());//打印显示model中namelist内容System.out.println(model.getNameList());System.out.println(model.getTe());}}测试结果:
[aa, bb]abc123[aa, bb, cc]def456[aa, bb, cc]abc123
发现model的内容发生变化了,再仔细观察是nameList发生变化了。
这说明对克隆对象的修改,影响了原始对象的内容!这可不是我们想看到的结果!这就是浅复制所带来的
结果。
(1)浅复制
Object类的clone方法只是复制本对象的原始数据类型,如int,float、String等,对于数组和对象引用
等是不会复制的。因此,浅复制是有风险的。如何才能完全克隆呢?这就需要深复制了。
(2)深复制
深复制是指对于对象中的数组和对象引用也做复制的行为,从而达到将对象完全复制的效果。
例如,可将上面例子中Model的Clone()方法进行修改,如下:
package com.demo.prototype.clonetest;import java.util.ArrayList;public class Model implements Cloneable {private String te = ""; private ArrayList<String> nameList= new ArrayList<String>(); public ArrayList<String> getNameList() {return nameList;}public String getTe() {return te;}public void putTe(String str) { te = str;}//添加内容public void add(String str){this.nameList.add(str);}//Clone方法@SuppressWarnings("unchecked")@Overridepublic Model clone(){try {Model model = (Model)super.clone();model.nameList = (ArrayList<String>) this.nameList.clone();//对数组进行复制return model;} catch (CloneNotSupportedException e) {e.printStackTrace();}return null;}}
测试结果:
[aa, bb]abc123[aa, bb, cc]def456[aa, bb]abc123
看,说明model和它的复制对象model2已经没有联系了。
从以上内容可以看到,Object的clone方法只是做浅复制,也就是直接复制类的字段内容,并不管属性字段对象的内容,我们可以在重载的clone方法中进行类的“深复制”,从而到达完全克隆的目的。
0 0
- 原型模式-2
- 设计模式--[2]原型模式
- 设计模式之原型模式2,prototype
- C++设计模式2-原型模式Prototype
- 原型模式
- 原型模式
- 原型模式
- 原型模式
- 原型模式
- 原型模式
- 原型模式
- 原型模式
- 原型模式
- 原型 模式
- 原型模式
- 原型模式
- 原型模式
- 原型模式
- 码农 黑客和2B程序员之间的区别
- 第二周项目- C/C++语言中函数参数传递的三种方式
- 第二周项目1
- Lua:Nginx Lua环境配置,使用openresty
- 给SQL Server字段加注释
- 原型模式-2
- ORACLE sid,pid,spid总结
- 第二周,C/C++语言中函数参与传递的三种方式
- c/c++语言中函数参数传递的三种方式
- Servlet完全教程
- jQuery实现星星评分样式
- Android Gradle基础
- linux下qt环境搭建
- ActionBar中的下拉菜单操作NAVIGATION_MODE_LIST