数组深拷贝和浅拷贝

时间:2014-03-06 07:03:21

标签: java arrays deep-copy shallow-copy

我正在学习深拷贝和浅拷贝。

如果我们有两个数组:

int[]arr1={1,2,3,4,5};
int[]arr2={1,2,3,4,5};

问题:两个数组都指向相同的引用[1][2][3][4][5]

如果我更改arr1[2]会怎样?是否会更改arr2[2]

当我们将一个数组(随机数组,不一定是arr1arr2)从main传递给方法时,编译器将数组的副本传递给方法, 对?

如果,则重新编写Java编译器以生成并向该方法发送数组数据副本。 主要原始阵列会发生什么?我认为原始数组可能会根据方法改变并传回主体。我不确定。

3 个答案:

答案 0 :(得分:3)

  

问题:两个阵列都指向相同的参考文献[1] [2] [3] [4] [5]。

不完全是。您的阵列具有相同的内容。话虽如此,根据您的初始化,他们使用的数据不是共享。然而,像这样初始化它会:

int[]arr1={1,2,3,4,5};
int[] arr2 = arr1
  

如果我改变arr1 [2]会发生什么?它是否会改变arr2 [2]?

根据上述问题的答案,不,不会。但是,如果你按照我指出的那个改变你的初始化机制,它就会。

  

当我们传递一个数组(随机数组,不一定是arr1或arr2)   从main到一个方法,编译器生成一个数组的浅表副本   对方法,对吧?

您的方法将收到一个查找阵列的位置,不会进行复制。

  

如果重写Java编译器以制作和发送深层副本   数组数据到方法。原始阵列会发生什么   主要的?我认为原始阵列可能会根据改变   方法并传回主要。我不确定。

如果您要创建数组的深层副本并将其发送到您的方法,并且您的方法将在该副本上运行,那么原始数组应该保持不变。

答案 1 :(得分:1)

使用值初始化数组将始终分配新内存。 对于“int [] arr1 = {1,2,3,4,5};” jvm将计算初始化数组的长度,并在内存中分配所需的空间量。在这种情况下,jvm为5个整数分配了内存。 当你执行“int [] arr2 = {1,2,3,4,5}”时,同样的事情再次发生(jvm为另外5个整数分配内存)。 因此改变arr1 [2]将不会反映arr [2]。

arr1[2]=10;
 System.out.println(arr2[2]); // this will still print 3

如果你想让arr2指向arr1的内容,你应该这样做:

int []arr2=arr1;

这将是一个浅层副本。这使得数组引用对象包含与arr1相同的值。现在,如果你这样做:

arr1[2]=10;
System.out.println(arr2[2]); //this will print 10.

现在,如果你想要对数组进行深层复制(而不是像你那样重复初始化),那么正确的命令就是:

int arr2[] = Arrays.copyOf(arr1, arr1.length);

这将表现得像第一个场景(您的代码 - 更改arr1不会影响arr2)。

答案 2 :(得分:0)

因为您有原始类型,所以您可以创建独立的数组。要展示深层和浅层副本:

MyObject a = new MyObject("a");
MyObject[] first = new MyObject[] {a};
MyObject[] second = new MyObject[] {a};
a.setName("b");
System.out.println(second[0].getName());
second[0].setName("c");
System.out.println(first[0].getName());