概要
原型模式是一种特殊的创建型模式,它通过复制一个已有对象来创建更多相同或者相似的对象。
浅拷贝
在浅拷贝中,如果原型对象的成员变量是基本数据类型,如int,float,String(这里的String也属于基本数据类型,暂时不知道原因),则复制一份给克隆对象,如果原型对象的成员变量是引用数据类型,则原型对象和克隆对象的成员变量指向相同的地址。
深拷贝
在深拷贝中,无论原型对象的成员变量是基本数据类型还是引用数据类型,都将复制一份给克隆对象。
Java中提供了Clone接口来实现浅拷贝,示例如下:
public class PrototypePerson {
public static void main(String[] args) throws CloneNotSupportedException {
Person person = new Person();
Person person1 = person.clone();
person.setAge(18);
person1.setAge(19);
System.out.println(person.getAge());
System.out.println(person1.getAge());
}
}
class Person implements Cloneable{
private int age;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
protected Person clone() throws CloneNotSupportedException {
return (Person)super.clone();
}
@Override
public String toString() {
return super.toString();
}
}
注:
如果将Person类中的age成员变量替换成某个类实例,则拷贝出来的成员变量和原型对象中的成员变量一定是一致的,下面采用深拷贝来解决这一问题。
深拷贝的过程采用了Java序列化的功能。示例如下:
import org.omg.CORBA.PERSIST_STORE;
import java.io.*;
public class PrototypePerson {
public static void main(String[] args) throws Exception {
Student student = new Student();
student.setAge(18);
Person person = new Person();
person.setStudent(student);
ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("F:\test\a.txt"));
objectOutputStream.writeObject(person);
ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("F:\test\a.txt"));
Person person1 = (Person) objectInputStream.readObject();
person1.getStudent().setAge(19);
System.out.println(person.getStudent().getAge());
System.out.println(person1.getStudent().getAge());
}
}
class Person implements Cloneable, Serializable {
private Student student;
public Student getStudent() {
return student;
}
public void setStudent(Student student) {
this.student = student;
}
@Override
protected Person clone() throws CloneNotSupportedException {
return (Person)super.clone();
}
@Override
public String toString() {
return super.toString();
}
}
class Student implements Serializable
{
private int age;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
注:这里Person内部的Student类也要实现Serializable接口,因为在Person类序列化的过程中,已经对Student做了序列化操作。



