foreach 循环是不是从字面上重写为带有迭代器的 for 循环? [复制]
Posted
技术标签:
【中文标题】foreach 循环是不是从字面上重写为带有迭代器的 for 循环? [复制]【英文标题】:Is foreach loop literally rewritten to a for loop with iterator? [duplicate]foreach 循环是否从字面上重写为带有迭代器的 for 循环? [复制] 【发布时间】:2014-06-11 01:58:45 【问题描述】:这个post解释了foreach循环直接对应于使用迭代器。如果我写一个 foreach 循环,它真的会被转换成 for with iterator 吗?特别是给定循环:
for(Integer i : createList())
System.out.println(i);
我是否保证无论如何都只调用一次createList()
?是否改写为:
for(Iterator<Integer> i = createList().iterator(); i.hasNext(); )
System.out.println(i.next());
在某种中间步骤中还是恰好产生与上述相同的字节码?
【问题讨论】:
How does the Java for each loop work? 的可能重复项 - 这个非常详细的答案的哪一部分,或者您不明白的任何dups here on SO? 我知道代码 sn-ps 是等价的。给出的一些答案说“它被翻译了”。我不明白编译器是从字面上将它与第二个 sn-p 交换还是只产生相同的输出。这样或那样我很好奇这种行为是由语言本身还是由编译器保证的。 @BrianRoach 您建议的副本不正确 - 它没有解决循环主题的多次评估问题。撤回您的投票并希望其他 VTC 使用我的副本可能是一个好主意。 @Duncan,你提到的帖子和 user1685993 提供的链接,解释了我对函数调用的主要关注。我仍然想知道翻译在实践中的样子(中间步骤或缺少中间步骤)。我认为如果没有中间步骤,可能更难保证结构总是完全等价的(我想对了吗?)。也许有人碰巧知道这一点:) 是否存在“真正的”翻译或只是等效的字节码输出无关紧要,因为 Java 编译器不需要输出它们的中间数据结构。只要字节码的输出是正确的,Java 编译器(除了 JDK 提供的编译器之外还有更多的编译器——比如 Eclipse 编译器)就可以做任何它想要的输出。 【参考方案1】:根据Oracle documentation,确实有代码在生成,但是根据使用的对象的类型不同。
如果您使用的是数组,则 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
【讨论】:
【参考方案2】:AFAIK,它没有经过翻译阶段,它只是为 Iterable 做同样的事情
一个区别是你不能在 for-each 中访问迭代器,这意味着你不能这样做
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
是组成的,对应用程序不可用。您也许可以在调试器中看到它们,但名称不同。
【讨论】:
以上是关于foreach 循环是不是从字面上重写为带有迭代器的 for 循环? [复制]的主要内容,如果未能解决你的问题,请参考以下文章