1

次のコード例で、コンストラクター ( )var1を変更せずにインスタンス フィールドを変更するにはどうすればよいですか? - を使用してコピーを作成する必要がありますか?initialVal1var2Arrays.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はなく、単なる変数です。それらの値は配列を参照しています...そして、それらは両方とも同じ配列を参照しています。それは、同じ家の住所が書かれた 2 枚の紙を持っているようなものです。1枚の紙の住所に従って家に加えた変更は、別の紙を使用して家を再度訪問すると明らかに表示されます. これは衒学のように聞こえるかもしれませんが、変数、その値、およびオブジェクトを区別すると、私の経験では人生がより明確になります。

2 つの独立した配列が必要な場合は、慎重に行う必要があります。たとえば、コンストラクタ本体を次のように変更できます。

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また、に置き換える必要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]
   }
  }
于 2013-09-28T18:49:50.763 に答える
0

あなたのコンストラクターでvar1は、実際には によって参照される同じ配列への別の参照initialVal1であるため、あなたが言ったように、一方の要素を変更すると、もう一方に影響します。

で配列全体をコピーArrays.copyOf()すればうまくいくはずですが、無駄です。ここでメモリ パフォーマンスが問題になる場合は、ある種のコピー オン ライト配列を実装する必要があります。

于 2013-09-28T18:50:35.383 に答える