深拷贝与浅拷贝

浅拷贝:在堆中创建了一个新对象,将原对象的字段值复制到新对象中,如果原对象中有引用类型字段,会直接复制引用到新对象中,原对象和新对象的引用类型属性指向同一块内存地址。

class Stu implements Cloneable{
    private int id;
    private String name;

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

class MyClass implements Cloneable{
    private int a;
    private Stu s;

    public int getA() {
        return a;
    }

    public void setA(int a) {
        this.a = a;
    }

    public Stu getS() {
        return s;
    }

    public void setS(Stu s) {
        this.s = s;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
         return super.clone();
    }
}


public class Test {
    public static void main(String[] args) throws CloneNotSupportedException {
        MyClass c1 = new MyClass ();
        MyClass c2 = (MyClass) c1.clone();
        System.out.println(c1.getA() == c2.getA()); //true
        System.out.println(c1.getS() == c2.getS()); //true
    }
}
  • MyClass中包含Stu引用类型属性,MyClass类实现了Cloneable接口,并重写了clone方法,内部是直接调用父类Object的clone()方法。
  • 只是浅拷贝,并没有将MyClass中的引用类型属性拷贝一份,而是直接复制了原来的引用地址

深拷贝:将所有属性都拷贝一份,包括引用类型,原对象和新对象不会共享引用,新对象是一个全新的对象。

public class Test {
    public static void main(String[] args) throws CloneNotSupportedException {
        MyClass2 c1 = new MyClass2();
        c1.setS(new Stu());
        MyClass2 c2 = (MyClass2) c1.clone();
        System.out.println(c1.getA() == c2.getA()); //true
        System.out.println(c1.getS() == c2.getS()); //false
    }
}


class MyClass2 implements Cloneable{
    private int a;
    private Stu s;

    public int getA() {
        return a;
    }

    public void setA(int a) {
        this.a = a;
    }

    public Stu getS() {
        return s;
    }

    public void setS(Stu s) {
        this.s = s;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        MyClass2 c = (MyClass2) super.clone();
        c.s = (Stu) s.clone();
        return c;
    }
}

class Stu implements Cloneable{
    private int id;
    private String name;

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
  • 修改了MyClass的clone方法实现,将引用类型属性也拷贝一份再赋给新对象,这样就是一个全新的对象了。(引用属性类也要实现Cloneable接口)
  • 这时c1.getS() == c2.getS()结果为false,证明了原对象和新对象的引用指向不同。

对于实现深拷贝的方式,还有序列化和反序列,手动递归复制等方式。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值