You can test it like this:
public static void main(tring[] args) {
for (String string : getList()) {
System.out.println(string);
}
}
private static List<String> getList() {
System.out.println("getList");
List<String> l = new ArrayList<String>();
l.add("a");
l.add("b");
return l;
}
... and you will find that getList() is only called once.
The syntax of the enhanced for() loop is:
for(Type item : iterable) ...
In your example, getList()
returns an Iterable
at runtime -- in this case a List
. Once it's done that, the loop gets to work with the one Iterable it needs.
for (String string : getList()) ...
and
List list = getList();
for (String string : list) ...
... are equivalent. The first form has the advantage of being short and clear. The second form has the advantage that you can use the list again afterwards, if you need to.
In Eclipse, you can switch between the two forms with an automatic refactoring (other IDEs have similar):
Starting with the first form, select getList()
, right click, Refactor
-> extract local variable
. Eclipse will prompt you for a variable name. Enter list
, and it will create the second form for you.
Starting with the second form, select list
in the for()
statement, right click, Refactor
-> Inline
. It will prompt, then change it back to the old format.
Refactorings are supposed to result in functionally identical code, so you can use this as evidence that the two forms are equivalent.
Take care however; other loop forms are not as clever.
while( size < file.length()) {
...
}
... executes file.length()
every time the loop iterates, whereas
long fileLength = file.length();
while( size < fileLength ) {
...
}
... executes file.length()
only once. The same applies to traditional for(;;)
loops.
The Eclipse refactoring transform described above will also switch between these two forms, but the behaviour is not the same.