我正在学习深拷贝和浅拷贝。
如果我们有两个数组:
int[]arr1={1,2,3,4,5};
int[]arr2={1,2,3,4,5};
问题:两个数组都指向相同的引用[1][2][3][4][5]
。
如果我更改arr1[2]
会怎样?是否会更改arr2[2]
?
当我们将一个数组(随机数组,不一定是arr1
或arr2
)从main传递给方法时,编译器将数组的浅副本传递给方法, 对?
如果,则重新编写Java编译器以生成并向该方法发送深数组数据副本。 主要原始阵列会发生什么?我认为原始数组可能会根据方法改变并传回主体。我不确定。
答案 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());