Answer 4 is technically correct, but not because a for(;;)
or "for each" loop is used instead of a while()
loop. It simply a matter of the Iterator's declared scope within the Class rather than the method. First, let's look at the behavior of the two methods hasNext()
and next()
:
The hasNext()
method simply queries an internal cursor (index); next()
actually advances the cursor, therefore that is the "modification" that could raise the exception. If you try to use an Iterator declared and assigned outside of the method in which next()
is being used, the code will throw an exception on the first next()
, regardless if it's a for(;;)
or while()
.
In Answer 4 and 8, the iterator is declared and consumed locally within the method. It just so happens that since the for(;;)
construct allows for a first time declaration and assignment of the iterator before the loop executes (which makes the iterator scoped to the for(;;)
and implicitly within the method, making it "safe"). I agree that the for(;;)
idiom is cleaner syntactically and fences scope at the lowest level of execution, completely within the for(;;)
loop.
Answer 8 is correct, because the Iterator is assigned and used locally inside the method.
But, just for sake of the discussion, the following method using a while()
statement is syntactically correct, "safe" and non-modifying from a scope and reference perspective:
somewhere in the Class definition
...
ArrayList<String> messageList;
somewhere in the class constructor
messageList = new ArrayList<String>();
add a method...
public printMessages ( )
{
Iterator<String> messageIterator = messageList.iterator();
while (messageIterator.hasNext())
{
System.out.println(messageIterator.next());
}
System.out.flush();
}