在以下示例代码中,如何在不更改构造函数(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;
}
}
答案 0 :(得分:4)
var1
和initialVal
不是数组 - 它们只是变量。它们的值将引用到数组......并且它们都引用相同的数组。就好像有两张纸都有相同的住宅地址。如果您再使用另一张纸再次访问房屋,那么您对房屋所做的任何更改都会显示在一张纸上。我知道这听起来像是迂腐,但是当你区分变量,它们的价值观和物体生活在我的经历中变得更加清晰。
如果你想要两个独立的阵列,你需要刻意这样做。例如,您可以将构造函数体更改为:
var1 = initialVal1.clone();
答案 1 :(得分:3)
是的,你必须克隆,因为两者都指的是同一个array
。
public Test(int[] initialVal1)
{
var1 = initialVal1.clone();// or Arrays.copyOf(initialVal1,initialVal1.length);
}
您在getSumOfInitial
必须将initialVal1
替换为var1
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]
}
}
答案 2 :(得分:0)
在构造函数中,var1
实际上是initialVal1
引用的同一数组的另一个引用,正如您所说,更改一个元素会影响另一个元素。
使用Arrays.copyOf()
复制整个数组应该可以解决问题,但这样做很浪费。
如果内存性能是一个问题,你应该实现某种写时复制数组。