深拷贝浅拷贝

学习C++和Java,一直对深拷贝/浅拷贝迷糊。今天咱就整明白它。

啥是浅拷贝?啥是深拷贝?

看下面的代码。

class Foo {
  private Bar myBar;
  ...
  public Foo shallowCopy() {
    Foo newFoo = new Foo();
    newFoo.myBar = myBar;
    return newFoo;
  }

  public Foo deepCopy() {
    Foo newFoo = new Foo();
    newFoo.myBar = myBar.clone(); //or new Bar(myBar) or myBar.deepCopy or ...
    return newFoo;
  }
}

Foo myFoo = new Foo();  
Foo sFoo = myFoo.shallowCopy();  
Foo dFoo = myFoo.deepCopy();  

myFoo.myBar == sFoo.myBar => true  
myFoo.myBar.equals(sFoo.myBar) => true  
myFoo.myBar == dFoo.myBar => **false**  
myFoo.myBar.equals(dFoo.myBar) => true  

 上面是java代码。很简单,写了个FOO类,里面有两个方法。一个shallowCopy方法就是传说中的浅拷贝;一个deepCopy方法,就是传说中的深拷贝。两个方法都是new了一个FOO对象,然后返回;唯一不同的是,两种方法,在对myBar这个引用处理的时候,有不一样的操作。咱们先来回顾下JVM内存模型。

上图为JVM负责存储的一个笼统的内存模型(更详细的看下探秘系列第一章)。上面我们说到的,myBar这个引用,就是存储在栈里,它指向堆中的一个对象。如果调用的是shallowCopy,那么返回的对象,其中的myBar还是指向堆中原来的那个对象的。如下图(盗了一张dog对象的,一个意思哈)。

 

再看deepCopy,这里面对myBar处理,使用了clone方法。java中clone,是一个native方法。实际上是在堆中又创建了一个一模一样的对象,然后myBar这个引用,指向了这个新的对象,如下图:

所以,就出现了最开始代码中的结果。如果是同一个对象,只是不同的引用,这样的拷贝就称为浅拷贝;如果是创建了一个新的对象,那就称之为深拷贝。

这就是所谓的深拷贝和浅拷贝。最关键的,就是看在堆里是怎么操作的。是同一个对象,还是又生出了个一模一样的新对象?栈中的引用,只是个表象而已。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

林小BA

请作者增肥

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值