关于java:foreach循环字面上是否用iterator重写为for循环?

Is foreach loop literally rewritten to a for loop with iterator?

本问题已经有最佳答案,请猛点这里访问。

这篇文章解释了foreach循环直接对应于使用迭代器。 如果我写一个foreach循环,它真的会转换成for for iterator? 特别是给定的循环:

1
2
3
for(Integer i : createList()){
    System.out.println(i);
}

无论如何,我保证总是只打电话给createList()一次吗? 它被重写为:

1
2
3
for(Iterator<Integer> i = createList().iterator(); i.hasNext(); ) {
    System.out.println(i.next());
}

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


根据Oracle的文档,确实生成了代码,但它根据所使用的obejct的类型而有所不同。

如果您正在使用数组,则foreach循环将被转换为带索引的for循环:

1
2
3
4
5
6
T[] #a = Expression;
L1: L2: ... Lm:
for (int #i = 0; #i < #a.length; #i++) {
    VariableModifiersopt TargetType Identifier = #a[#i];
    Statement
    }

如果你有一个Iterable对象,你会得到一个迭代器循环,如下所示:

1
2
3
4
for (I #i = Expression.iterator(); #i.hasNext(); ) {
    VariableModifiersopt TargetType Identifier = (TargetType) #i.next();
    Statement
}

AFAIK,它没有经历翻译阶段,它只对Iterable做同样的事情

一个区别是你不能在for-each中访问Iterator,这意味着你不能这样做

1
2
3
for(Integer i: createList()) {
   if (i == 5) iter.remove(); // or whatever the iterator is called.
}

但你可以做到

1
2
3
4
5
for(Iterator<Integer> iter = createList().iterator(); iter.hasNext(); ) {
    Integer i = iter.next();

    if (i == 5) iter.remove();
}

注意:如果有的话

1
public Integer[] createList();

然后

1
2
3
for(Integer i : createList()){
    System.out.println(i);
}

是相同的

1
2
3
4
5
6
7
{
    Integer[] $arr = createList();
    for(int $i = 0; $i < $arr.length; $i++) {
        Integer i = $arr[$i];
        System.out.println(i);
    }
}

注意:变量$arr$i组成,并且不可用于应用程序。 您可以在调试器中使用不同的名称查看它们。