@Tyhj
2019-01-29T17:23:34.000000Z
字数 1674
阅读 1057
设计模式
用原型实例指定创建对象的种类,并通过拷贝这些原型创建新对象
- 类的初始化需要消耗非常多的数据、硬件资源,通过拷贝来避免消耗
- new 一个对象非常的麻烦,可能需要各种权限
- 一个对象需要给其他对象使用,而且会被改变,为了保护这个对象,可以使用原型模式
其实就是复制一个已存在的实例,来避免重新创建对象的一些麻烦。但是有时候使用拷贝不一定更高效,需要自己来判断是否使用
实现其实很简单,只需要这个类实现Cloneable
接口,然后重写一下clone
方法就好了,Cloneable
接口只是一个标志接口,没有任何方法,clone
方法是Object
自带的方法,实现了接口才能使用clone
方法
随便写个文档的类,保存标题、介绍、图片这些内容,实现Cloneable接口,然后重写一下clone
public class Essay implements Cloneable{
private String title;
private String introduction;
private ArrayList<String> imgs;
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
...
}
初始化后,拷贝这个类
String title = "原型模式";
String introduction = "介绍一";
ArrayList<String> imgs = new ArrayList<>();
imgs.add("图片一");
Essay essay = new Essay(title, introduction, imgs);
Essay essay1= (Essay) essay.clone();
System.out.println(essay1.toString());
输出拷贝对象如下,其实不重写clone
方法也完全可以拷贝出来,就是说默认就会拷贝变量
Essay{title='原型模式', introduction='介绍一', imgs=[图片一]}
但是我们改一下程序,把拷贝过来的对象的值改变一下,再输出原对象的值
essay1.imgs.add("嘿嘿嘿");
System.out.println(essay.toString());
输出如下,发现原imgs
的值被改变了
Essay{title='原型模式', introduction='介绍一', imgs=[图片一, 嘿嘿嘿]}
这个表明,拷贝的对象只是一个引用了原对象的变量而已,当拷贝对象发生了变化,原对象也变了;
拷贝的对象只是一个引用了原对象的变量,这个就是浅拷贝;在我们改变了拷贝对象的值的时候,原对象也会改变;
深拷贝肯定就是真正意义上的拷贝,拷贝对象不会对原对象产生影响,方法也很简单;我们可以看到其实基本类型是没有引用的,所以拷贝的时候肯定是没有问题的,不用考虑的基本类型;所以只需要在拷贝对象的时候,对于引用型的字段也采用拷贝的形式就可以了;
@Override
protected Object clone() throws CloneNotSupportedException {
Essay essayClone= (Essay) super.clone();
essayClone.imgs= (ArrayList<String>) imgs.clone();
return essayClone;
}
再次运行,原对象的值的确没有被改变
Essay{title='原型模式', introduction='介绍一', imgs=[图片一]}
但是其中有一个问题就是,如果改变拷贝的String对象的值,原值会不会被改变;其实是不会的,String类比较特殊,因为String是在内存中不可以被改变的对象,String自身没有方法可以改变自身的值;所以要是你的类没有可以改变自身值,也可以不用考虑,本质还是引用,如果用==
来判断会返回true
使用原型模式就是为了更高效的创建对象,最好是使用深拷贝,避免影响原始对象