原型模式的思想就是将一个对象作为原型,对其进行复制、克隆产生一个和原对象类似的新对象。
一个原型类,只需要实现Cloneable接口,覆写clone方法调用super.clone(),此处clone方法可以改成任意的名称,因为Cloneable接口是个空接口,你可以任意定义实现类的方法名,如cloneA或者cloneB,重点是super.clone()这句话,super.clone()调用的是Object的clone()方法,而在Object类中,clone()是native的,这个不在详细介绍
克隆分两种:
- 浅复制
新对象的简单类型和String类型可以复制为新的,但是引用对象还是和原对象的一样
- 深复制
完全复制一个新的对象(属性都是新的)
代码示例:
/**
* 原型模式
*
* @author zhouzhongyi
*
*/
public class Anestor implements Cloneable, Serializable {
private static final long serialVersionUID = 1L;
// 简单类型或者String类型
private String name;
// 引用类型
private SerializableObject object;
/* 浅复制 */
public Object clone() throws CloneNotSupportedException {
Anestor proto = (Anestor) super.clone();
return proto;
}
/*
* 深复制
*
* 要实现深复制,需要采用流的形式读入当前对象的二进制输入,再写出二进制数据对应的对象。
*/
public Object deepClone() throws IOException, ClassNotFoundException {
/* 将对象序列化到二进制流 */
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(this);
/* 从二进制流中读出产生的新对象 */
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);
return ois.readObject();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public SerializableObject getObject() {
return object;
}
public void setObject(SerializableObject object) {
this.object = object;
}
}
//定义一个类
class SerializableObject implements Serializable {
private static final long serialVersionUID = 1L;
}
public class AnestorDemo {
public static void main(String[] args) throws Exception{
// 创建原对象
Anestor anestor= new Anestor();
prototype.setName("zzy");
prototype.setObject(new SerializableObject());
System.out.println("克隆之前的对象:"+anestor.getName());
System.out.println("克隆之前的对象:"+anestor.getObject());
// 浅复制出来的对象
Anestor clone = (Anestor) anestor.clone();
System.out.println("浅复制出来的对象:"+clone.getName());
System.out.println("浅复制出来的对象:"+clone.getObject());
// 深复制出来的对象
Anestor deepClone = (Anestor) anestor.deepClone();
System.out.println("深复制出来的对象:"+deepClone.getName());
System.out.println("深复制出来的对象:"+deepClone.getObject());
}
}