1

在以下示例代码中,如何var1在不更改initialVal1构造函数 ( var2) 中的情况下更改实例字段?- 我应该使用复制Arrays.copyOf吗?

public class Test
{
 private int[] var1;
 private int[] var2;

 public Test(int[] initialVal1)
 {
  var1 = initialVal1;
  var2 = initialVal1;
 }

 private void int mutateVar1()
 {
  this.var1[0] = 100;  // change the value at index 0 to 100 in var1 array, this also changes initialVal[0], right?
 }

 private int getSumOfInitial()
 { 
   int sum = 0;
   for (int i = 0; i < var2.length; i++) // but at this point, the initialVal[0] has also been mutated to 100.
   {
     sum += var2[i]
   }
   return sum;
  }
 }
4

3 回答 3

4

var1并且initialVal不是数组 - 它们只是变量。它们的值引用一个数组......并且它们都引用同一个数组。这就像有两张纸,上面都有相同的家庭地址。如果您随后使用另一张纸再次访问该房屋,那么您按照一张纸上的地址对房屋所做的任何更改显然都是可见的。我知道这听起来像迂腐,但是当你区分变量、它们的值和对象时,我的经验会变得更加清晰。

如果你想要两个独立的数组,你需要故意这样做。例如,您可以将构造函数主体更改为:

var1 = initialVal1.clone();
于 2013-09-28T18:49:27.550 回答
3

是的,您必须克隆,因为两者都指的是相同的array.

public Test(int[] initialVal1)
 {
  var1 = initialVal1.clone();// or Arrays.copyOf(initialVal1,initialVal1.length);
 }

你也有一个错误getSumOfInitial必须更换initialVal1var1

private int getSumOfInitial()
 { 
   int sum = 0;
   for (int i = 0; i < var1.length; i++) // but at this point, the var1[0] has also been mutated to 100.
   {
     sum += var1[i]
   }
  }
于 2013-09-28T18:49:50.763 回答
0

在您的构造函数中,var1实际上是对 引用的同一数组的另一个引用initialVal1,因此正如您所说,更改一个元素会影响另一个元素。

复制整个数组Arrays.copyOf()应该可以解决问题,但这很浪费。如果这里的内存性能是一个问题,您应该实现某种写时复制数组。

于 2013-09-28T18:50:35.383 回答