The answer is in the Java Language Specification, not need to decompile :) This is what we can read about the enhanced for statement:
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 expression
Expression.iterator(). The enhanced for statement is equivalent
to a basic for statement of the
form:
for (I #i = Expression.iterator(); #i.hasNext(); ) {
VariableModifiersopt Type Identifier = #i.next();
Statement
}
Where #i is a compiler-generated
identifier that is distinct from any
other identifiers (compiler-generated
or otherwise) that are in scope (§6.3)
at the point where the enhanced for
statement occurs.
Otherwise, the Expression necessarily
has an array type, T[]. Let L1 ... Lm
be the (possibly empty) sequence of
labels immediately preceding the
enhanced for statement. Then the
meaning of the enhanced for statement
is given by the following basic for
statement:
T[] a = Expression;
L1: L2: ... Lm:
for (int i = 0; i < a.length; i++) {
VariableModifiersopt Type Identifier = a[i];
Statement
}
Where a and i are compiler-generated
identifiers that are distinct from any
other identifiers (compiler-generated
or otherwise) that are in scope at the
point where the enhanced for statement
occurs.
In your case, myMap.keySet() returns a subtype of Iterable so your enhanced for statement is equivalent to the following basic for statement:
for (Iterator<String> iterator = myMap.keySet().iterator(); iterator.hasNext();) {
String key = iterator.next();
System.out.println(key);
System.out.println(myMap.get(key));
}
And myMap.keySet() is thus called only once.