foreach循环是否用迭代器重写为for循环?

时间:2014-04-25 11:23:38

标签: java foreach compilation syntactic-sugar

这个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());
}

在某种中间步骤中或恰好产生与上述相同的字节码?

2 个答案:

答案 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已组成,并且不可用于应用程序。您可以在调试器中看到它们,并使用不同的名称。