多くの場合、2 つの構造は互換性がありますが、100% 同等というわけではありません!!!
// code goes here
証明は、2 つの構造の動作が異なるように定義することによって構築できます。そのようなループ本体の 1 つを次に示します。
arr = null;
したがって、現在比較しています。
char[] arr = new char[5];
for (char x : arr) {
arr = null;
}
と:
char[] arr = new char[5];
for (int i = 0; i < arr.length; i++) {
char x = arr[i];
arr = null;
}
どちらのコードもコンパイルされますが、実行すると、最初のループは正常に終了し、2 番目のループはNullPointerException
.
これは、それらが 100% 同等ではないことを意味します。2 つのコンストラクトの動作が異なるシナリオがあります。
このようなシナリオはめったに発生しない可能性がありますが、デバッグ時にこの事実を忘れてはなりません。
補足として、インデックスが必要な場合など、for-each コンストラクトがオプションではない場合があることに注意してください。ここでの重要な教訓は、それがオプションであっても、常に保証されているわけではないため、実際に同等の代替品であることを確認する必要があるということです。
同様に、for-each ループから始めて、後でインデックス付き for ループに切り替える必要があることに気付いた場合は、保証されていないため、セマンティクスを保持していることを確認してください。
特に、_反復される配列/コレクションの参照への変更には注意してください_ (コンテンツへの変更はトリガーされる場合とトリガーされない場合がありますConcurrentModificationException
が、それは別の問題です)。
カスタム反復子を使用するコレクションを使用する場合、セマンティクスの保持を保証することもはるかに困難ですが、この例が示すように、単純な配列が含まれている場合でも、2 つの構造は異なります。