Один сценарий, который я могу придумать, где NullPointerException
будет выброшен во втором случае, это когда addCard
или dealCard
каким-то образом изменяют то, к чему относится players
(предположительно, ни один из них не изменяет содержимое players
, потому что это вызвало бы ConcurrentModificationException
в первом фрагменте).
Вот пример (пожалуйста, запустите его самостоятельно, если у вас есть какие-либо сомнения):
import java.util.*;
public class ForEachVS {
static List<Integer> players;
static void process(int i) {
System.out.println(i);
players = null;
}
public static void main(String args[]) {
players = Arrays.asList(1,2,3);
for (int p : players) {
process(p);
} // this processes 1,2,3
players = Arrays.asList(1,2,3);
for (int i = 0; i < players.size(); i++) {
process(players.get(i));
} // this processes 1, then throws NullPointerException
}
}
Так что, как вы можете видеть, две конструкции на самом деле НЕ точно эквивалентны. Суть приведенного фрагмента кратко представлена здесь:
int[] arr;
arr = new int[5];
for (int x : arr) {
arr = null;
}
arr = new int[5];
for (int i = 0; i < arr.length; i++) {
arr = null;
}
Вы обнаружите, что первый цикл прошел нормально, а второй цикл выдает NullPointerException
. Поэтому, хотя в большинстве случаев это так, эти две конструкции не совсем точно эквивалентны .