java基础专题

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);
    }
上一篇下一篇

猜你喜欢

热点阅读