このコードで、配列が希望どおりに初期化されないのはなぜですか? for-each ループはそれを行うように設計されていませんか、それとも正しく使用していないだけですか?
int[] array = new int[5];
//initialise array -> Doesn't work! Array still full of 0's
for(int i : array)
i = 24;
この場合、for-each ループは機能しません。for-each ループを使用して配列を初期化することはできません。あなたのコード:
int[] array = new int[5];
for (int i : array) {
i = 24;
}
次のようなものに変換されます。
int[] array = new int[5];
for (int j = 0; j < array.length; j++) {
int i = array[j];
i = 24;
}
これがオブジェクトの配列である場合でも、失敗します。基本的に、for-each は、コレクションまたは配列内の各エントリを、指定した変数に割り当てます。この変数を使用して作業できます。変数は配列参照と同等ではありません。それは単なる変数です。
For-each を使用して配列またはコレクションを初期化することはできません。これは、配列またはコレクションの現在の内容をループして、各値を一度に 1 つずつ与えるためです。for-each の変数は、配列またはコレクション参照のプロキシではありません。i
コンパイラは、 (" " からのint i
) " " を " "に置き換えませんarray[index]
。
たとえば、日付の配列があり、これを試すと、コードは次のようになります。
Date[] array = new Date[5];
for (Date d : array) {
d = new Date();
}
は次のように翻訳されます。
Date[] array = new Date[5];
for (int i = 0; i < array.length; i++) {
Date d = array[i];
d = new Date();
}
ご覧のとおり、配列は初期化されません。すべてヌルを含む配列になります。
注: 上記のコードを.class
ファイルにコンパイルし、 jadを使用して逆コンパイルしました。このプロセスにより、上記のコードから Sun Java コンパイラ (1.6) によって生成された次のコードが得られます。
int array[] = new int[5];
int ai[];
int k = (ai = array).length;
for(int j = 0; j < k; j++)
{
int i = ai[j];
i = 5;
}
i
配列内のその時点の int の単なるコピーであり、参照ではありません。この場合、for-each ループは機能しません。
使用する
java.util.Arrays.fill(array, 24)
同じ値に初期化する場合。それ以外では、Eddie は for-each コンストラクトの翻訳においてかなり適切です。
int はシステムのプリミティブ型であるため、実際には、割り当て可能な配列内のセルへの参照ではなく、配列内のセルの値のコピーを取得しています....
これを説明してみましょう。X の配列がある場合 (X はデータ メンバーを持つクラス)、反復ごとに異なるセルへの参照を取得し、関数 (setValue など) を呼び出すことでその状態を変更できます。 .
int がある場合は別の話です。int は参照ではなく、プリミティブ型であるためスタック上の実際の値です。したがって、各反復で for は配列から i に値をコピーします。次に i を更新しますが、配列には影響しません。
代わりにこれを行います:
int[] array = new int[5];
// initialise array -> Will work now
for(int i = 0 ; i< array.length ; i++)
array[i] = 24 ;