One scenario I can think of where a NullPointerException
will be thrown in the second case is when addCard
or dealCard
somehow changes what players
refer to (presumably neither modifies the content of players
, because that would cause a ConcurrentModificationException
in the first snippet).
Here's an example (please run this on your own if you have any doubts):
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
}
}
So as you can see, the two constructs are actually NOT exactly equivalent. The essence of the above snippet is concisely presented here:
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;
}
You will find out that the first loop went fine, while the second loop throws NullPointerException
. So while it's true most of the time, the two constructs are not exactly 100% equivalent.