原型模式
简介
- 用原型实例制定创建对象的种类的,并且通过拷贝这些原型,创建新的对象。
- 是一种创建型模式。
浅拷贝和深拷贝
浅拷贝
- 对于是基本数据类型的成员变量,会直接进行值传递,将该属性的值复制一份给新的对象。
- 对于数据类型是引用类型(数组,对象),则是引用传递。
- 默认方式浅拷贝。
实现方式
实现Cloneable
接口:
class Student implements Cloneable {
// ... 省略其他信息
@Override
protected Object clone() throws Clone() {
return super.clone();
}
}
深拷贝
- 复制对象的所有基本数据类型的成员变量的值。
- 为引用数据类型申请新的存储空间,并复制每个引用数据类型成员变量所引用的对象。
实现方式
- 第一种 :重写
Clone
方法来实现深度拷贝。
public class Student implements Serializable, Cloneable {
private String name;
private int age;
private Student friend;
@Override
protected Object clone() throws CloneNotSupportedException {
// 1. 先克隆
Student stu = (Student) super.clone();
// 2. 对象成员单独处理
stu.friend = (Student) this.friend.clone();
return stu;
}
}
- 第二种 :通过序列化实现深度拷贝。
public class Student implements Serializable, Cloneable {
private String name;
private int age;
private Student friend;
@Override
protected Object clone() throws CloneNotSupportedException {
Student stu = null;
ByteArrayOutputStream outbuffer = null;
ObjectOutputStream outputStream = null;
ByteArrayInputStream inbuffer = null;
ObjectInputStream inputStream = null;
try {
// 1. 将当前对象的字节输出到一个缓冲区当中, 序列化。
outbuffer = new ByteArrayOutputStream();
outputStream = new ObjectOutputStream(outbuffer);
outputStream.writeObject(this);
// 2. 从缓冲区当中读取数据,反序列化。
inbuffer = new ByteArrayInputStream(outbuffer.toByteArray());
inputStream = new ObjectInputStream(inbuffer);
// 3. 拷贝
stu = (Student) inputStream.readObject();
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
} finally {
// 关闭流 :
try {
outbuffer.close();
outputStream.close();
inbuffer.close();
inputStream.close();
} catch (IOException | NullPointerException e) {
e.printStackTrace();
}
}
return stu;
}
}