设计模式—原型模式
定义
用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象
代码
原型的核心就是通过clone() 方法来创建对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| public class Thing implements Cloneable {
private String name; private List<String> addressList = new ArrayList<>();
public Thing() { System.out.println("构造函数执行了"); }
@Override protected Thing clone() { Thing thing =null; try { thing = (Thing) super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return thing; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public List<String> getAddressList() { return addressList; }
public void setAddressList(String address) { this.addressList.add(address); } }
|
上面的原型类实现了Cloneable 接口,并重写了clone 方法。
测试:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| public class ThingTest {
public static void main(String[] args) { Thing thing = new Thing(); thing.setName("游戏"); thing.setAddressList("北京"); Thing thing2 = thing.clone(); thing2.setName("读书"); System.out.println(thing.getName()+"--"+thing2.getName()); thing2.setAddressList("上海"); System.out.println(thing2.getAddressList()); System.out.println(thing.getAddressList());
} }
|
由测试结果可以看到,拷贝的时候构造函数不执行 并且 引用的全局变量(不包括String)在clone的时候是浅拷贝,只是拷贝了其引用地址,这是需要改变下原型的clone方法来进行深拷贝
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| public class Thing implements Cloneable {
private String name; private ArrayList<String> addressList = new ArrayList<>();
public Thing() { System.out.println("构造函数执行了"); }
@Override protected Thing clone() { Thing thing =null; try { thing = (Thing) super.clone(); thing.addressList = (ArrayList<String>) this.addressList.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return thing; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public List<String> getAddressList() { return addressList; }
public void setAddressList(String address) { this.addressList.add(address); } }
|
List 声明改成ArrayList,并在clone方法里将addressList进行clone,这时候再去运行测试代码就发现addressList的内容就不相互影响了。