1.浅复制
我们先来看浅复制是什么。对于要实现克隆(我们后面将浅复制和深复制统称为克隆),必须实现Cloneable接口,尽管clone方法在Object类里,但我们还是得实现Cloneable接口不然会抛出CloneNotSupportedException错误。
定义一个Resume类实现Cloneable接口,并实现Object类中的clone方法。
public class Resume implements Cloneable {
private String name;
private String sex;
private Test test = new Test();
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getSex() { return sex; }
public void setSex(String sex) { this.sex = sex; }
public Test getTest() { return test; }
public void setTest(Test test) { this.test = test; }
@Override
protected Object clone() throws CloneNotSupportedException {
Resume resume = (Resume)super.clone();
return resume;
}
}
public class Main {
public static void main(String[] args) throws CloneNotSupportedException {
Resume resume1 = new Resume();
Resume resume2 = (Resume)resume1.clone();
System.out.println(resume1.hashCode() + " " + resume2.hashCode());
System.out.println(resume1.getTest().hashCode() + " " + resume2.getTest().hashCode());
}
}
我们可以看看输出结果,resume2是否只是复制了resume1的引用:
756151793,1982445652
1856320770,1856320770
我们看到虽然我们对resume1进行了克隆,resume2确实也是新的引用,但由于Resume类中有了对另外一个类的引用,所以resume1和resume2对Test对象的引用还是同一个,这就是浅复制。
2.深复制
那么如何做到连同Test对象一起克隆,而不是只复制一个引用呢?这就是深复制的概念。
package day_12_prototype;
/**
* @author turbo
*
* 2016年9月17日
*/
public class Test implements Cloneable{
private String test;
public String getTest() {
return test;
}
public void setTest(String test) {
this.test = test;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
package day_12_prototype;
/**
* @author turbo
*
* 2016年9月17日
*/
public class Resume implements Cloneable {
private String name;
private String sex;
private Test test = new Test();
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Test getTest() {
return test;
}
public void setTest(Test test) {
this.test = test;
}
@Override
protected Object clone() throws CloneNotSupportedException {
Resume resume = (Resume)super.clone();
resume.test = (Test)test.clone();
return resume;
}
}
package day_12_prototype;
/**
* @author turbo
*
* 2016年9月17日
*/
public class Main {
/**
* @param args
* @throws CloneNotSupportedException
*/
public static void main(String[] args) throws CloneNotSupportedException {
Resume resume1 = new Resume();
Resume resume2 = (Resume)resume1.clone();
System.out.println(resume1.hashCode() + " " + resume2.hashCode());
System.out.println(resume1.getTest().hashCode() + " " + resume2.getTest().hashCode());
}
}
输出结果:
756151793,1982445652
1856320770,1857264482
这样我们就实现了对象的深复制。
说完浅复制与深复制,其实我们也就讲完了原型模式:用原型实例指定创建对象的种类,
并且通过拷贝这些原型创建新的对象。为什么要通过克隆的方式来创建新的对象,也即是
我们在上面提到的,每new一次都需要执行一次构造函数,如果构造函数的执行时间很长,
那么多次执行这个初始化操作就实在是太低效了。