答えはJava言語仕様にあり、逆コンパイルする必要はありません:)これは、拡張されたforステートメントについて読むことができるものです:
拡張forステートメントの形式は次のとおりです。
EnhancedForStatement:
for ( VariableModifiersopt Type Identifier: Expression) Statement
式は型
Iterable
であるか、配列型(§10.1)である必要があります。そうでない場合、コンパイル時エラーが発生します。
for
拡張ステートメント(§14.14)のFormalParameter部分で宣言されたローカル変数のスコープは、含まれているステートメントです。
拡張ステートメントの意味はfor
、基本ステートメントへの翻訳によって与えられfor
ます。
Expression
のタイプがのサブタイプである場合、式のタイプとIterable
しI
ます
。iterator()
。拡張ステートメントは、次の形式for
の基本ステートメントと同等です。for
for (I #i = Expression.iterator(); #i.hasNext(); ) {
VariableModifiersopt Type Identifier = #i.next();
Statement
}
#i
拡張forステートメントが発生する時点でスコープ(§6.3)にある他の識別子(コンパイラー生成またはその他)とは異なるコンパイラー生成識別子はどこにありますか。
それ以外の場合、式には必ず配列型がありT[]
ます。拡張ステートメントL1 ... Lm
の直前の(おそらく空の)ラベルのシーケンスとしfor
ます。次に、拡張forステートメントの意味は、次の基本for
ステートメントによって与えられます。
T[] a = Expression;
L1: L2: ... Lm:
for (int i = 0; i < a.length; i++) {
VariableModifiersopt Type Identifier = a[i];
Statement
}
ここで、aおよびiは、拡張forステートメントが発生する時点でスコープ内にある他の識別子(コンパイラー生成またはその他)とは異なるコンパイラー生成の識別子です。
あなたの場合、myMap.keySet()
のサブタイプを返すIterable
ので、拡張ステートメントは次の基本ステートメントfor
と同等です。for
for (Iterator<String> iterator = myMap.keySet().iterator(); iterator.hasNext();) {
String key = iterator.next();
System.out.println(key);
System.out.println(myMap.get(key));
}
myMap.keySet()
したがって、一度だけ呼び出されます。