1.为什么要使用原型模式
原型模式讲到底,就是覆写了 Object的 clone()接口。但是这个clone是直接从内存复制的,效率比new 一个对象高了很多。
2.类图
一个邮件类,只有接收者和内容,obj是用于测试的。该邮件类实现了Cloneable接口,也就可以覆写clone()方法了。
3.原型模式的实现
public class Mail implements Cloneable{
private String receiver;//接收人
private String content;//内容
private Object obj;//测试
@Override
public Mail clone(){
Mail mail = null;
try {
mail = (Mail) super.clone();
}catch (CloneNotSupportedException e){
e.printStackTrace();
}
return mail;
}
//getter/setter
public String getReceiver() {
return receiver;
}
public void setReceiver(String receiver) {
this.receiver = receiver;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public Object getObj() {
return obj;
}
public void setObj(Object obj) {
this.obj = obj;
}
}
main方法
public class Main {
public static void main(String[] args) {
Mail mail1 = new Mail();
mail1.setReceiver("hr");
mail1.setContent("context");
mail1.setObj(new Object());
Mail mail2 = mail1.clone();
//hash 地址不同
System.out.println(mail1.hashCode());
System.out.println(mail2.hashCode());
//但是属性相同,包括对象,也就是说obj是同一个对象
System.out.println(mail2.getReceiver());
System.out.println(mail2.getContent());
System.out.println(mail2.getObj().hashCode());
System.out.println(mail1.getObj().hashCode());
}
}
//输出(你们的HashCode可能不太一样,但是最后两个肯定是相同的)
614573570
1889132567
hr
context
105332674
105332674
其中Mail类的clone方法,是clone通用的方法,也就是说换成其它类用相同的写法就行了。
4.谈谈深复制和浅复制
深复制和浅复制的区别:深复制不仅复制该对象本身(复制的对象和原对象hashCode不同),而且还复制原对象的引用对象(比如Mail引用了Object,那么深复制会把这个Object也复制出全新的一份,hashCode不同);浅复制就是只复制该对象本身(复制的对象和原对象hashCode不同),但是不复制该对象的引用对象(引用对象的HashCode相同,就像是上面的Mail例子,就是浅复制)。
5.那么深复制怎么实现?
一种方法:在实现clone的方法时,把引用对象也都clone一份。
第二种方法:反射+递归,通过反射获得其所有引用对象,再把其所有引用对象进行clone(),比第一种更加通用,也比较麻烦。
第三种方法:用序列化的方法,(效率其低无比,还要考虑transient关键字)
6.最后说一句
博主目前没用到啥需求需要clone的,一般都是直接new,也不知道搞这么多理论干啥子= =