创建重复的对象,同时保证性能。当通过new创建对象的代价比较大时,考虑使用。 JAVA 通过继承 Cloneable,重写 clone()实现。
优点:
- 性能提高。
- 逃避构造函数的约束。
缺点:
- 配备克隆方法需要对类的功能进行通盘考虑,这对于全新的类不是很难,但对于已有的类不一定很容易,引用含有循环结构的时候。
- 必须实现 Cloneable 接口
注意事项:浅拷贝和深拷贝
public class Text implements Cloneable {
private int num;
// 引用数据类型,String也是会指向字符串常量池中的同一个对象
public Photo photo;
public Text() {
photo = new Photo("test");
}
public void setPhoto(String url) {
photo.setUrl(url);
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
@Override
public Text clone() throws CloneNotSupportedException {
Text text = (Text) super.clone();
// text.photo = text.photo.clone();
// 对引用的克隆,这样就不会指向同一地址
text.photo = this.photo.clone();
return text;
}
public static class Photo implements Cloneable {
String url;
public Photo(String url) {
this.url = url;
}
public void setUrl(String url) {
this.url = url;
}
public String getUrl() {
return url;
}
@Override
protected Photo clone() throws CloneNotSupportedException {
return (Photo) super.clone();
}
}
}
public static void main(String[] args) {
Text text = new Text();
text.setNum(10);
System.out.println(text.getNum()+""+text.photo.url); // 10 test
try {
Text text1 = text.clone();
text1.setNum(22);
text1.setPhoto("hehehehe");
System.out.println(text1.getNum()+""+text1.photo.url); // 22 hehehehe
System.out.println(text.getNum()+""+text.photo.url); // 10 test 若浅拷贝,则结果和text1一样
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}