我想浅拷贝它,所以我不能这样做:
int[] 浅= orig;
那不是真正的浅拷贝。副本是与原始项目相似但不是原始项目的离散实体。在您的示例中,您实际上拥有的是两个指向同一个对象的引用。创建副本时,您应该有两个结果对象:原始对象和副本。
在这里,您所做的任何修改shallow
都会发生,orig
因为它们都指向同一个对象。
当您正在比较的对象具有对其中其他对象的引用时,“浅薄”就会发挥作用。例如,如果您有一个整数数组并创建了一个副本,那么您现在有两个数组都包含相同的整数值:
Original Array
[0]
[1]
[2]
[3]
After copying:
[0] <--- Original [0]
[1] [1]
[3] [2]
[4] Copy ---> [3]
但是,如果你有一个由对象组成的数组(比如说objArr1
and objArr2
)呢?当你做一个浅拷贝时,你现在有两个新的数组对象,但是两个数组之间的每个对应条目都指向同一个对象(因为对象本身没有被复制;只是引用有)。
Original Array:
[0:]----> [object 0]
[1:]----> [object 1]
[2:]----> [object 2]
[3:]----> [object 3]
复制后(注意相应的位置如何指向相同的实例):
Original -> [0:]----> [object 0] <----[:0] <- Copy
[1:]----> [object 1] <----[:1]
[2:]----> [object 2] <----[:2]
[3:]----> [object 3] <----[:3]
现在,如果您objArr1
通过替换条目或删除条目进行修改,同样的事情不会发生在objArr2
. 但是,如果您在 处修改对象objArr1[0]
,也会反映在 中objArr2[0]
,因为这些位置指向同一个对象。所以在这种情况下,即使容器对象本身是不同的,它们所包含的是对同一对象的引用。
当您进行深度复制时,您将创建两个新数组,其中每个对应位置指向不同的实例。所以基本上你一直在复制对象。
我的教授说,对于原语,浅拷贝和深拷贝本质上是相同的,因为我们必须复制数组的每个索引。
要做出的重要区别是,当您复制一个基元数组时,您正在完全复制这些值。每次你得到一个新的原语。然而,当你有一个对象数组时,你真正拥有的是一个对对象的引用数组。因此,当您创建副本时,您所做的就是创建一个新数组,其中包含原始数组中引用的副本。但是,这些引用的新副本仍然指向相同的对应对象。这就是所谓的浅拷贝。如果您对数组进行深度复制,那么每个单独位置所引用的对象也将被复制。所以你会看到这样的东西:
Original -> [0:]----> [object 0] Copy -> [0:]----> [copy of object 0]
[1:]----> [object 1] [1:]----> [copy of object 1]
[2:]----> [object 2] [2:]----> [copy of object 2]
[3:]----> [object 3] [3:]----> [copy of object 3]
但是设置整个数组等于另一个数组做同样的事情,对吧?
不,不是的。您在这里所做的只是创建对现有数组的新引用:
arr1 -> [0, 1, 2, 3, 4]
现在假设你做到了arr2 = arr1
。你所拥有的是:
arr1 -> [0, 1, 2, 3, 4] <- arr2
所以这里arr1
, 和arr2
都指向同一个数组。因此,您使用的任何修改arr1
都将在您访问数组时反映出来,arr2
因为您正在查看同一个数组。制作副本时不会发生这种情况。