概念
学完这个模式,就觉得这个模式怎么不叫克隆模式,就是实现一个克隆,也是一个名字而已,前人总结得出的(也不见得老婆饼有老婆,是吧?),当直接创建对象的代价比较大时,则采用这种模式。
实现
案例:假如在未来的某个时候,克隆技术正式普及了,我们需要对一只猫咪进行克隆,那么这个猫咪就得具备克隆的特性,借下来我们来定义一下这个猫咪的类:
我们要对这个名为小白的白猫进行克隆:
/**
* 定义一个白猫的类,实现Cloneable接口,实现克隆
*/
public class WhiteCat implements Cloneable{
//定义白猫的一个属性,姓名——小白
private String name = "小白";
//定义一个小黑,是小白的男朋友
private BlackCat blackCat = new BlackCat("小黑");
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
public BlackCat getBlackCat() {
return blackCat;
}
public void setBlackCat(BlackCat blackCat) {
this.blackCat = blackCat;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
其中小白还有个男朋友黑猫(小黑)的类进行定义:
/**
* 定义黑猫的类
*/
public class BlackCat {
//定义一个属性
private String name;
public BlackCat(String name) {
this.name = name;
}
@Override
public String toString() {
return "BlackCat{" +
"name='" + name + '\'' +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
好了进行克隆实验:
/**
* 浅克隆:只是把克隆对象复制一遍,对于被克隆对象的某些属性没有进行复制
*/
public class ShallowClone {
public static void main(String[] args) throws CloneNotSupportedException {
//定义w1是小白
WhiteCat w1 = new WhiteCat();
//进行克隆高科技,克隆出小白2号
WhiteCat w2 = (WhiteCat) w1.clone();
System.out.println("小白2号的名字:" + w2.getName());
System.out.println("小白2号的男朋友:" + w2.getBlackCat());
//判断小白和小白2号的男朋友是不是同一个
System.out.println(w1.getBlackCat() == w2.getBlackCat());
}
}
实验结果:
大家觉得是不是上面的这个实验就已经成功了,是不是大家忘记一样东西呢,小白和小白2号的男朋友都是同一个,这怎么也不合理吧,男朋友怎么能共用呢,还是得一人配备一个,那么就是我们得深度克隆,下面呈现代码:
/**
* 定义一个白猫的类,实现Cloneable接口,实现克隆
*/
public class WhiteCat implements Cloneable{
//定义白猫的一个属性,姓名——小白
private String name = "小白";
//定义一个小黑,是小白的男朋友
private BlackCat blackCat = new BlackCat("小黑");
@Override
public Object clone() throws CloneNotSupportedException {
WhiteCat whiteCat = (WhiteCat)super.clone();
whiteCat.blackCat = (BlackCat)blackCat.clone();
return whiteCat;
}
public BlackCat getBlackCat() {
return blackCat;
}
public void setBlackCat(BlackCat blackCat) {
this.blackCat = blackCat;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
黑猫也得具备克隆的特性:
/**
* 定义黑猫的类
*/
public class BlackCat implements Cloneable{
//定义一个属性
private String name;
public BlackCat(String name) {
this.name = name;
}
@Override
public String toString() {
return "BlackCat{" +
"name='" + name + '\'' +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
进行深度克隆
/**
* 深度克隆:对克隆对象进行深度克隆,特别是对某些属性
* 在这里,我们需要直到那些属性需要进行克隆;
* 需要克隆的属性通常为Object,基本数据类型的值都是在常量池中,所以不需要重新克隆
*/
public class DeepClone {
public static void main(String[] args) throws CloneNotSupportedException {
//定义w1是小白
WhiteCat w1 = new WhiteCat();
//进行克隆高科技,克隆出小白2号
WhiteCat w2 = (WhiteCat) w1.clone();
System.out.println("小白2号的名字:" + w2.getName());
System.out.println("小白2号的男朋友:" + w2.getBlackCat());
//判断小白和小白2号的男朋友是不是同一个
System.out.println(w1.getBlackCat() == w2.getBlackCat());
}
}
实验结果:
优点:减少之间创建对象造成的代价,不用考虑构造函数有多复杂,从而提高性能。
本文的代码:https://pan.baidu.com/s/1khmHMn3d_SzPmhG8bEXXew
提取码:hfw2