前往顾页
以后地位: 主页 > 收集编程 > Jsp实例教程 >

java常常利用设想形式原型形式及深浅拷贝

时候:2018-01-09 23:57来源:知行网www.zhixing123.cn 编辑:麦田守望者

原型形式(Prototype Pattern)是用于建立反复的工具,同时又能包管机能。这类范例的设想形式属于建立型形式,它供应了一种建立工具的最好体例。

java常用设计模式原型模式及深浅拷贝

Prototype类需求具有以下两个前提:

1、实现Cloneable接口。在java说话有一个Cloneable接口,它的感化只需一个,就是在运行时告诉假造机可以宁静地在实现了此接口的类上利用clone体例。在java假造机中,只需实现了这个接口的类才可以被拷贝,不然在运行时会抛出CloneNotSupportedException异常。

2、重写Object类中的clone体例。Java中,所有类的父类都是Object类,Object类中有一个clone体例,感化是前往工具的一个拷贝,但是其感化域protected范例的,一般的类无法调用,是以,Prototype类需求将clone体例的感化域点窜成public范例。

原型形式是一种比较简朴的形式,也非常容易了解,实现一个接口,重写一个别例即完成了原型形式。在实际利用中,原型形式很少伶仃呈现。常常与其他形式混用,他的原型类Prototype也常常利用笼统类来替代。

原型形式-深浅拷贝

浅拷贝:只复制一个工具,工具外部存在的指向其他工具数组或援引则不复制。

深拷贝:工具,工具外部的援引均复制。

Object类的clone体例只会拷贝工具中的根基的数据范例,对数组、容器工具、援引工具等都不会拷贝,这就是浅拷贝。如果要实现深拷贝,必须将原型形式中的数组、容器工具、援引工具等另行拷贝

原型形式-深浅拷贝实现

浅拷贝:

调用 java.lang.Object的clone()体例

深拷贝:

1、工具外部所有援引型工具都进行clone。

2、工具序列化

先来看下浅拷贝的代码:

import java.io.ByteArrayInputStream;

import java.io.ByteArrayOutputStream;

import java.io.IOException;

import java.io.ObjectInputStream;

import java.io.ObjectOutputStream;

import java.io.Serializable;

import java.util.ArrayList;

class Prototype implements Cloneable {

private static final long serialVersionUID = -1251595400978173322L;

private ArrayList<String> list = new ArrayList<>();

private int mInt;

public ArrayList<String> getList() {

return list;

}

public void setList(ArrayList<String> list) {

this.list = list;

}

public int getmInt() {

return mInt;

}

public void setmInt(int mInt) {

this.mInt = mInt;

}

public Prototype clone() {

Prototype prototype = null;

try {

prototype = (Prototype) super.clone();

} catch (CloneNotSupportedException e) {

e.printStackTrace();

}

return prototype;

}

}

Client类:

import java.util.ArrayList;

public class Client {

public static void main(String[] args) {

Prototype cp = new Prototype();

cp.setmInt(10);

ArrayList list = new ArrayList<>() ;

list.add(“原型形式”) ;

cp.setList(list);

Prototype clonecp = cp.clone();

System.out.println(“mInt:”+clonecp.getmInt());

System.out.println(“list:”+clonecp.getList());

cp.setmInt(20);

list.add(“clone后的原型形式”) ;

cp.setList(list);

System.out.println(“mInt:”+clonecp.getmInt());

System.out.println(“list:”+clonecp.getList());

}

}

运行成果:

java常用设计模式原型模式及深浅拷贝

可以看出,浅拷贝后,原型工具中的援引范例值改变,拷贝的工具援引范例的值也跟着转变,实际上浅拷贝的工具外部援引范例工具和原型工具外部的援引范例工具指向同一援引。clone这类工具的时候需求重视,如果希望拷贝的工具不受原型工具的影响,浅拷贝就不合用了。

接上去看深拷贝,深拷贝有2种实现体例:

1、工具中的每个援引工具都进行clone。

import java.io.ByteArrayInputStream;

import java.io.ByteArrayOutputStream;

import java.io.IOException;

import java.io.ObjectInputStream;

import java.io.ObjectOutputStream;

import java.io.Serializable;

import java.util.ArrayList;

class Prototype implements Cloneable {

private static final long serialVersionUID = -1251595400978173322L;

private ArrayList<String> list = new ArrayList<>();

private int mInt;

public ArrayList<String> getList() {

return list;

}

public void setList(ArrayList<String> list) {

this.list = list;

}

public int getmInt() {

return mInt;

}

public void setmInt(int mInt) {

this.mInt = mInt;

}

public Prototype clone() {

Prototype prototype = null;

try {

prototype = (Prototype) super.clone();

// deep clone

prototype.list = (ArrayList) this.list.clone();

} catch (CloneNotSupportedException e) {

e.printStackTrace();

}

return prototype;

}

}

还是用之前的Client类,运行成果以下:

java常用设计模式原型模式及深浅拷贝

此时 ,clone后,即便原型工具中list的值改变,也不会影响clone工具。

2、深拷贝第二种体例:经由过程工具序列化

这类体例需求原型工具实现序列化接口,代码以下:

import java.io.ByteArrayInputStream;

import java.io.ByteArrayOutputStream;

import java.io.IOException;

import java.io.ObjectInputStream;

import java.io.ObjectOutputStream;

import java.io.Serializable;

import java.util.ArrayList;

class Prototype implements Cloneable,Serializable {

private static final long serialVersionUID = -1251595400978173322L;

private ArrayList<String> list = new ArrayList<>();

private int mInt;

public ArrayList<String> getList() {

return list;

}

public void setList(ArrayList<String> list) {

this.list = list;

}

public int getmInt() {

return mInt;

}

public void setmInt(int mInt) {

this.mInt = mInt;

}

/**

* 深拷贝

* @return

*/

public Prototype deepClone() { // 利用序列化和反序列化实现深复制

try {

ByteArrayOutputStream bos = new ByteArrayOutputStream();

ObjectOutputStream oos = new ObjectOutputStream(bos);

oos.writeObject(this);

byte[] bytes = bos.toByteArray();

ByteArrayInputStream bis = new ByteArrayInputStream(bytes);

ObjectInputStream ois = new ObjectInputStream(bis);

return (Prototype) ois.readObject(); // 克隆好的工具

} catch (IOException e) {

e.printStackTrace();

} catch (ClassNotFoundException e) {

e.printStackTrace();

}

return null;

}

}

Client类:

import java.util.ArrayList;

public class Client {

public static void main(String[] args) {

Prototype cp = new Prototype();

cp.setmInt(10);

ArrayList list = new ArrayList<>() ;

list.add(“原型形式”) ;

cp.setList(list);

Prototype clonecp = cp.deepClone();

System.out.println(“mInt:”+clonecp.getmInt());

System.out.println(“list:”+clonecp.getList());

cp.setmInt(20);

list.add(“clone后的原型形式”) ;

cp.setList(list);

System.out.println(“mInt:”+clonecp.getmInt());

System.out.println(“list:”+clonecp.getList());

}

}

运行成果:

java常用设计模式原型模式及深浅拷贝

可以看出,运行成果和第一种体例一样,实现了深拷贝。

利用原型形式建立工具比直接new一个工具在机能上要好的多,因为Object类的clone体例是一个本处所法,它直接操纵内存中的二进制流,特别是复制年夜工具时,机能的不同非常较着。另外一方面,克隆回避机关函数的束缚。

顶一下
(0)
0%
踩一下
(0)
0%
------分开线----------------------------
标签(Tag):Java Java开辟标准
------分开线----------------------------
颁发评论
请自发遵循互联网相关的政策法规,严禁公布色情、暴力、革命的谈吐。
评价:
神色:
考证码:点击我更换图片
猜你感兴趣