I have this for-each-loop:
for (Component c : container.getComponents()) {
// Loop code
}
Is getComponents
called on every iteration? Does it make sense to call getComponents
before the look and only work on a cached array?
No, getComponents() will only be called once.
It's the equivalent of:
for (Iterator<Component> iterator = container.getComponents().getIterator();
iterator.hasNext(); )
{
Component c = iterator.next();
...
}
From section 14.14.2 of the Java Language Specification:
The enhanced for statement has the form:
EnhancedForStatement:
for ( VariableModifiersopt Type Identifier: Expression) Statement
The Expression must either have type Iterable or else it must be of an array type (§10.1), > or a compile-time error occurs. The scope of a local variable declared in the FormalParameter part of an enhanced for statement (§14.14) is the contained Statement
The meaning of the enhanced for statement is given by translation into a basic
for
statement.If the type of Expression is a subtype of
Iterable
, then let I be the type of the expressionExpression.iterator()
. The enhanced for statement is equivalent to a basicfor
statement of the form:for (I #i = Expression.iterator(); #i.hasNext(); ) { VariableModifiersopt Type Identifier = #i.next(); Statement }
getComponents will be called once, and will return an Iterator. This iterator will then be called using next() and hasNext() methods.
Update Here's a bit more detail in attempt to out Skeet Jon Skeet on this answer.
The following program shows how the call to iterator
is made once, even though there are three items in the collection.
public static void main(String[] args) {
List<String> list = new ArrayList<String>() {
public java.util.Iterator<String> iterator() {
System.out.println("iterator() called");
return super.iterator();
};
};
list.add("a");
list.add("b");
list.add("c");
for (String s : list) {
System.out.println(s);
}
}
Output:
iterator() called
a
b
c
If you run this through a Java decompiler, you'll find the following code:
String s;
for(Iterator iterator = list.iterator(); iterator.hasNext(); System.out.println(s))
s = (String)iterator.next();
Addtionally, since we know from the JLS 14.14.1 that the first section of a for statement is only executed once, we can rest assured that iterator method won't be called multiple times.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With