Java里的浅拷贝和深层拷贝区别(shadow copy, deep copy)

java拷贝引用
int a[] = {1,2};
int b[] = a;
System.out.println(a[0]);   //print 1
System.out.println(b[0]);   //print 1
a[0]=10000;
System.out.println(a[0]);   //print 10000
System.out.println(b[0]);   //print 10000 也随着a[0]改变而改变

如上所示我们其实只是将对象的引用从a传递给了b,当我们改变a的值时,b的值也会跟着改变。这不算真正的copy。

java浅层拷贝对象和深层拷贝

假设现在有对象obj1,它包含两个子对象containedObj1和containedObj2.


a.PNG

浅层拷贝就是创建一个新的实例,在内存中开辟新的地址生成obj2,但是obj2的子对象却没有被拷贝obj1的子对象,而是拷贝的obj1子对象的引用。


b.PNG

下面ArrayList里的clone()就是一个浅层拷贝的方法

ArrayList a = new ArrayList();
a.add(1);a.add(2)
ArrayList b = (ArrayList) a.clone();
System.out.println(a.get(0));   //print 1
System.out.println(b.get(0));   //print 1
a.set(0, 10000);
System.out.println(a.get(0));   //print 10000
System.out.println(b.get(0));   //print 1 没有随着a[0]改变而改变

然而当ArrayList里不是int类型而是其他对象类型时:

ArrayList<ArrayList> a = new ArrayList();
ArrayList objectInArr = new ArrayList();
objectInArr.add(1);
objectInArr.add(2);
a.add(objectInArr);
ArrayList<ArrayList> b = (ArrayList) a.clone();
System.out.println(a.get(0).get(0));   //print 1
System.out.println(b.get(0).get(0));   //print 1
objectInArr.set(0, 10000);
System.out.println(a.get(0).get(0));   //print 10000
System.out.println(b.get(0).get(0));   //print 10000 再次随着改变了

所以我们发现浅层拷贝拷贝不了子对象,这里就要用到深层拷贝。深层拷贝就是obj2不仅拷贝了obj1并且拷贝了obj1的所有子对象。


c.PNG

通常对于深层拷贝,我们需要根据情况自己构造一个函数来进行拷贝,来确保正确的复制。

推荐阅读更多精彩内容

  • 在 JS 中有一些基本类型像是Number、String、Boolean,而对象就是像这样的东西{ name: '...
    tobAlier阅读 338评论 0 0
  • 内存管理 简述OC中内存管理机制。与retain配对使用的方法是dealloc还是release,为什么?需要与a...
    丶逐渐阅读 1,481评论 1 16
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 29,071评论 18 398
  • 保存仿真每个仿真可以用包含数据的文本文件(.txt)格式或表格图像形式保存在工作区目录中。若要保存仿真数据:1.在...
    橡果阅读 132评论 0 0
  • 文/织绢 第一话:夏小夕 夏天仿佛突然就来了,听着头顶风扇的呼呼声,真切地感受着时间的流逝。看着高三的学长学姐低头...
    织绢阅读 216评论 0 3
  • 行动的速度是迫切的而不是孤注一掷的。中周末马上就要来了,感觉到时间很紧迫,今天完成了 《父母的觉醒》读后感,...
    郑清文阅读 85评论 0 1
  • 老子是道家学派的代表人,他主张清静无为的思想,对战国时期纷乱的时局起了中和作用。他撰写的《道德经》充满了智慧...
    flh1972831阅读 415评论 1 1