java基础专题:1.浅拷贝与深拷贝
2018-12-27 本文已影响0人
北交吴志炜
1.浅拷贝:如果一个类含有对象属性,那么调用默认的clone方法,这个对象属性拷贝的只是地址,比如BClass有一个对象属性AClass a,调用clone方法生成克隆对象之后,源对象与拷贝对象里面的属性a指向同一地址,此时改变a的值
源对象与拷贝对象里面的a的值都会一起改变。
public class BClass implements Cloneable {
private String name;
private AClass a;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public AClass getA() {
return a;
}
public void setA(AClass a) {
this.a = a;
}
public BClass(String name) {
this.name = name;
}
public static void main(String[] args) throws CloneNotSupportedException {
AClass a = new AClass("a");
BClass b1 = new BClass("b");
b1.setA(a);
BClass b2 = (BClass) b1.clone();
System.out.println(b2.getA().getName());
a.setName("aa");
System.out.println(b2.getA().getName());
}
}
AClass就是简单的一个name属性
public class AClass {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public AClass(String name) {
this.name = name;
}
}
深拷贝:对象属性不要去拷贝地址,真正的去拷贝值。
如何实现呢?
在BClass中重写clone() 即可,手动构造一个a属性对象,塞到克隆对象中。
public BClass clone() throws CloneNotSupportedException {
BClass b = (BClass) super.clone();
b.setA(new AClass(this.a.getName()));
return b;
}
再次重新跑,就不会出现浅拷贝的问题了。
如果AClass的属性name不是String,也是一个对象Name呢,怎么实现深拷贝?
所有的对象属性,都需要手动的构造然后塞进去,比如
new AClass(new Name());
public BClass clone() throws CloneNotSupportedException {
BClass b = (BClass) super.clone();
b.setA(new AClass(new Name(this.a.getName().getName())));
return b;
}
以上这些方法全是垃圾,真正好用的使用第三方的序列化工具,比如fastJson等,这么来重写clone
public CloneTest clone(){
return JSON.toJavaObject((JSON)JSON.toJSON(this),CloneTest.class);
}