1 简介
用原型实例指定创建对象的种类,并且通过复制这个原型来创建新的对象。原型模式包含深克隆和浅克隆两种形式。
浅克隆:对于基本类型成员变量,复制值;对于引用类型成员变量,复制对象地址;
深克隆:对于基本类型成员变量,复制值;对于引用类型成员变量,复制对象;
2 Cloneable接口和Serializable接口
Cloneable接口和Serializable接口代码都非常简单,它们都是空接口,如下:
public interface Cloneable {
}
public interface Serializable {
}
这种空接口也称为标识接口,标识接口中没有任何方法的定义,其作用是告诉JRE 这些接口的实现是否具有某些功能,是否支持克隆、是否支持序列化等。
3 代码
3.1 浅克隆
(1)原型(Prototype)
public class Prototype implements Cloneable{
int intValue;
String strValue;
Prototype(int intValue,String strValue){
this.intValue=intValue;
this.strValue=new String(strValue);
}
public Object clone() {
Object copy=null;
try {
copy=super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return copy;
}
public void show() {
System.out.println("intValue:"+intValue+"\tstrValue:"+strValue);
}
}
(2)客户端(Client)
public class Client {
public static void main(String[] args) {
Prototype prototype=new Prototype(0,"abc");
Prototype prototype2=(Prototype) prototype.clone();
System.out.println(prototype==prototype2); //false
System.out.println(prototype.intValue==prototype2.intValue); //true
System.out.println(prototype.strValue==prototype2.strValue); //true
}
}
注意:能够实现克隆的类,必须实现 Cloneable 接口,标识这个类支持复制。
由于 String 类没有实现 Cloneable 接口,因此,以下代码不能通过编译。
String s=new String("abc");
String s2=s.clone();
3.2 深克隆
(1)原型(Prototype)
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
public class Prototype implements Serializable{
int intValue;
String strValue;
Prototype(int intValue,String strValue){
this.intValue=intValue;
this.strValue=new String(strValue);
}
public Object clone() {
Object copy=null;
try {
//将对象写入流中
ByteArrayOutputStream bao=new ByteArrayOutputStream();
ObjectOutputStream oos=new ObjectOutputStream(bao);
oos.writeObject(this);
//将对象从流中取出
ByteArrayInputStream bis=new ByteArrayInputStream(bao.toByteArray());
ObjectInputStream ois=new ObjectInputStream(bis);
copy=ois.readObject();
}catch (Exception e) {
e.printStackTrace();
}finally{
bao.close();
oos.close();
bis.close();
ois.close();
}
return copy;
}
public void show() {
System.out.println("intValue:"+intValue+"\tstrValue:"+strValue);
}
}
(2) 客户端(Client)
public class Client {
public static void main(String[] args) {
Prototype prototype=new Prototype(0,"abc");
Prototype prototype2=(Prototype) prototype.clone();
System.out.println(prototype==prototype2); //false
System.out.println(prototype.intValue==prototype2.intValue); //true
System.out.println(prototype.strValue==prototype2.strValue); //false
}
}
注意:能够实现序列化的对象,其类必须实现 Serializable 接口,标识这个类支持序列化。
String 类也实现了 Serializable 接口,因此可以被序列化。其源码如下:
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {