为了快速的创建相似的对象。原型模式是通过拷贝自身来创建新的对象,使用原型模式创建对象比直接new一个对象在性能上要好的多,,因为Object类的clone方法是一个本地方法,它直接操作内存中的二进制流,特别是复制大对象时,性能的差别非常明显。。比如需要在一个循环体内创建对象,假如对象创建过程比较复杂或者循环次数很多的话,使用原型模式不但可以简化创建过程,而且可以使系统的整体性能提高很多。使用原型模式复制对象不会调用类的构造方法。深拷贝与浅拷贝。Object类的clone方法只会拷贝对象中的基本的数据类型,对于数组、容器对象、引用对象等都不会拷贝,这就是浅拷贝。如果要实现深拷贝,必须将原型模式中的数组、容器对象、引用对象等另行拷贝。深拷贝与浅拷贝问题中,会发生深拷贝的有java中的8中基本类型以及他们的封装类型,另外还有String类型。其余的都是浅拷贝。
浅拷贝:是指拷贝引用,实际内容并没有复制,改变后者等于改变前者。
深拷贝:拷贝出来的东西和被拷贝者完全独立,相互没有影响。
深拷贝:拷贝出来的东西和被拷贝者完全独立,相互没有影响。
/**
* 实现Cloneable接口,重写clone()方法,实现深拷贝
* @author zhangej
*
*/
public class Mail implements Cloneable{
private String mTitle;
private String mContent;
private ArrayList<String> mList = new ArrayList<String>();
public Mail(String title,String content){
mTitle = title;
mContent = content;
}
public String getmTitle() {
return mTitle;
}
public void setmTitle(String mTitle) {
this.mTitle = mTitle;
}
public String getmContent() {
return mContent;
}
public void setmContent(String mContent) {
this.mContent = mContent;
}
public ArrayList<String> getmList() {
return mList;
}
public void setmList(ArrayList<String> mList) {
this.mList = mList;
}
public void addList(String str) {
mList.add(str);
}
@SuppressWarnings("unchecked")
@Override
protected Object clone() throws CloneNotSupportedException {
// TODO Auto-generated method stub
Mail mail = (Mail)super.clone();
mail.mList = (ArrayList<String>) mList.clone();
return mail;
}
public void showMail(){
System.out.println("=====Start=====");
System.out.println("mTitle:"+mTitle);
System.out.println("mContent:"+mContent);
for(String list : mList){
System.out.println("list:"+list);
}
System.out.println("======End======");
System.out.println(" ");
}
}
/**
* 原型模式调用,从运行结果可以看出克隆的副本之间是相互独立的
* @author zhangej
*
*/
public class Main {
public static void main(String[] args) throws CloneNotSupportedException {
Mail mail1 = new Mail("标题1", "内容1");
mail1.addList("List1");
mail1.showMail();
//将mail1自身复制了一份,mail2是独立的一份对象
Mail mail2 = (Mail) mail1.clone();
mail2.showMail();
//测试 深拷贝,更改mail2的内容
mail2.setmTitle("标题2");
mail2.setmContent("内容2");
mail2.addList("List2深度拷贝成功!!!!");
mail2.showMail();
//mail1保持原来的数据不改变
mail1.showMail();
}
}
/*=====Start=====
mTitle:标题1
mContent:内容1
list:List1
======End======
=====Start=====
mTitle:标题1
mContent:内容1
list:List1
======End======
=====Start=====
mTitle:标题2
mContent:内容2
list:List1
list:List2深度拷贝成功!!!!
======End======
=====Start=====
mTitle:标题1
mContent:内容1
list:List1
======End======*/