这个post解释了foreach循环直接对应于使用迭代器。如果我写一个foreach循环,它真的会转换成for for iterator?特别是,给定循环:
for(Integer i : createList()){
System.out.println(i);
}
我保证无论什么时候总是只召唤createList()
一次?它被重写为:
for(Iterator<Integer> i = createList().iterator(); i.hasNext(); ) {
System.out.println(i.next());
}
在某种中间步骤中或恰好产生与上述相同的字节码?
答案 0 :(得分:5)
根据Oracle documentation,确实生成了代码,但它根据所使用的obejct的类型而有所不同。
如果您正在使用数组,则foreach循环将被转换为带索引的for循环:
T[] #a = Expression;
L1: L2: ... Lm:
for (int #i = 0; #i < #a.length; #i++) {
VariableModifiersopt TargetType Identifier = #a[#i];
Statement
}
如果你有一个 Iterable 对象,你会得到一个带迭代器的循环:
for (I #i = Expression.iterator(); #i.hasNext(); ) {
VariableModifiersopt TargetType Identifier = (TargetType) #i.next();
Statement
}
答案 1 :(得分:1)
AFAIK,它没有经历翻译阶段,它对Iterable做了同样的事情
一个区别是你不能以for-each的形式访问Iterator,这意味着你不能这样做
for(Integer i: createList()) {
if (i == 5) iter.remove(); // or whatever the iterator is called.
}
但你可以做到
for(Iterator<Integer> iter = createList().iterator(); iter.hasNext(); ) {
Integer i = iter.next();
if (i == 5) iter.remove();
}
注意:如果你有
public Integer[] createList();
然后
for(Integer i : createList()){
System.out.println(i);
}
与
相同{
Integer[] $arr = createList();
for(int $i = 0; $i < $arr.length; $i++) {
Integer i = $arr[$i];
System.out.println(i);
}
}
注意:变量$arr
和$i
已组成,并且不可用于应用程序。您可以在调试器中看到它们,并使用不同的名称。