1. 定义
原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
2. 实现
2.1 Cloneable接口clone方法
2.1.1 Product
实现Cloneable接口clone方法,clone方法中编写深拷贝逻辑
class Product implements Cloneable {private String part1;private String part2;private String part3;private String part4;private Info info;public Product(String part1, String part2, String part3, String part4, Info info) {this.part1 = part1;this.part2 = part2;this.part3 = part3;this.part4 = part4;this.info = info;}public String getPart1() {return part1;}public void setPart1(String part1) {this.part1 = part1;}public String getPart2() {return part2;}public void setPart2(String part2) {this.part2 = part2;}public String getPart3() {return part3;}public void setPart3(String part3) {this.part3 = part3;}public String getPart4() {return part4;}public void setPart4(String part4) {this.part4 = part4;}public Info getInfo() {return info;}public void setInfo(Info info) {this.info = info;}@Overridepublic String toString() {return this.hashCode() + " Product{" +"part1='" + part1 + '\'' +", part2='" + part2 + '\'' +", part3='" + part3 + '\'' +", part4='" + part4 + '\'' +", info=" + info +'}';}@Overrideprotected Product clone() throws CloneNotSupportedException {//深拷贝Product clone = (Product) super.clone();Info info = this.info.clone();clone.setInfo(info);return clone;}}
Info作为product的属性,同样实现Cloneable的clone方法,以便实现深拷贝
class Info implements Cloneable {private String name;public Info(String name) {this.name = name;}public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic String toString() {return this.hashCode() + " prototype.Info{" +"name='" + name + '\'' +'}';}@Overrideprotected Info clone() throws CloneNotSupportedException {return (Info) super.clone();}}
2.1.2 使用及测试
public static void main(String[] args) throws CloneNotSupportedException {Info info1 = new Info("info1");Product product = new Product("part1", "part2", "part3", "part4", info1);//cloneProduct clone = product.clone();//打印对比System.out.println("original: "+product);System.out.println("clone: "+clone);//打印结果:可以看到hashcode 不一样,说明已经实现了深拷贝// original: 460141958 Product{part1='part1', part2='part2', part3='part3', part4='part4', info=1163157884 prototype.Info{name='info1'}}// clone: 1956725890 Product{part1='part1', part2='part2', part3='part3', part4='part4', info=356573597 prototype.Info{name='info1'}}//修改info打印对比product.getInfo().setName("info2");System.out.println("original: "+product);System.out.println("clone: "+clone);// 打印结果:修改原始product.info后,clone.info没有变化,说明实现了深拷贝// original: 460141958 Product{part1='part1', part2='part2', part3='part3', part4='part4', info=1163157884 prototype.Info{name='info2'}}// clone: 1956725890 Product{part1='part1', part2='part2', part3='part3', part4='part4', info=356573597 prototype.Info{name='info1'}}}
2.2 序列化机制实现(不推荐)
修改clone实现逻辑
@Overrideprotected Product clone() throws CloneNotSupportedException {//深拷贝// Product clone = (Product) super.clone();// Info info = this.info.clone();// clone.setInfo(info);// return clone;ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();try (ObjectOutputStream oss = new ObjectOutputStream(byteArrayOutputStream)) {oss.writeObject(this);} catch (IOException e) {e.printStackTrace();}ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());try (ObjectInputStream ois = new ObjectInputStream(byteArrayInputStream)) {Product product = null;product = (Product) ois.readObject();return product;} catch (IOException e) {e.printStackTrace();} catch (ClassNotFoundException e) {e.printStackTrace();}return null;}
3. 应用场景
当代码不应该依赖于需要复制的对象的具体类时,请使用Prototype模式 。
