- 概念
用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象,简单理解就是拷贝
在Java中实现原型模式十分简单,只需要实现Cloneable接口并重写clone()方法就可以了
-
Code
package com.tanoak.create.prototype; public class Apple implements Cloneable{ private String name ; private String color ; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getColor() { return color; } public void setColor(String color) { this.color = color; } public Apple() { System.out.println("正在构造苹果,无参"); } public Apple(String name, String color) { System.out.println("正在构造苹果,有参"); this.name = name; this.color = color; } @Override protected Apple clone() throws CloneNotSupportedException { return (Apple)super.clone(); } }
-
测试
public class Main { public static void main(String[] args) throws Exception { test1(); } public static void test1() throws CloneNotSupportedException { Apple redApple = new Apple("红富士","红色"); System.out.println(redApple); Apple blueApple = redApple.clone(); /* blueApple.setColor("青色");*/ System.out.println(blueApple); } }
从以下运行结果可以看出构方法只执行了一次,就生成了两个对象
看到这里一切都很正常,但是,当我对Apple类增加引用类型
- Code
-
public class Apple implements Cloneable{
private String name ;
private String color ;
private ArrayList<Integer> list ;
public ArrayList getList() {
return list;
}
public void setList(ArrayList<Integer> list) {
this.list = list;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public Apple() {
System.out.println("正在构造苹果,无参");
}
public Apple(String name, String color) {
System.out.println("正在构造苹果,有参");
this.name = name;
this.color = color;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
@Override
public String toString() {
return "Apple{" +
"name='" + name + '\'' +
", color='" + color + '\'' +
", list=" + list +
'}';
}
}
-
测试
public class Main { public static void main(String[] args) throws Exception { test1(); } public static void test1() throws CloneNotSupportedException { Apple redApple = new Apple("红富士","红色"); ArrayList<Integer> arrayList = new ArrayList() ; arrayList.add(1) ; arrayList.add(2) ; redApple.setList(arrayList); Apple blueApple = (Apple)redApple.clone(); blueApple.setColor("青色"); blueApple.getList().remove(1) ; System.out.println(blueApple); System.out.println(redApple); } }
List的值被改变了,由此引出一个结论‘浅拷贝’
1. 对于引用类型,只拷贝其引用 2. 不能完全做到保护性拷贝
现在再次对clone() 方法进行改造,引出‘深拷贝’
-
Code
@Override protected Apple clone() throws CloneNotSupportedException { Apple clone = (Apple) super.clone(); clone.list = (ArrayList<Integer>) list.clone(); return clone; }
再次运行的结果如下
由此就达到了深拷贝的效果
-
-
优点
- 对象的创建非常复杂,可以使用原型模式快捷的创建对象,不需要知道创建细节。
- clone方法是由虚拟机直接复制内存块执行,速度比使用new的方式创建对象要快。