在java增强的for循环中,可以安全地假设要循环的表达式只会被评估一次吗?

时间:2009-10-24 15:02:33

标签: java arrays foreach iteration

在Java中,for-each循环。
如果我有一个生成数组的方法,名为genArray()

在下面的代码中,每次调用genArray()都会重新生成数组吗? 或者Java会调用一次方法并从数组中存储副本吗?

for (String s : genArray())
{
    //...
}

由于

3 个答案:

答案 0 :(得分:23)

关于the enhanced for statement,Java语言规范写道:

  

增强的for语句有   形式:

EnhancedForStatement:
        for ( VariableModifiersopt Type Identifier: Expression) Statement
     

Expression必须具有类型   Iterable或者它必须是   数组类型(第10.1节),或编译时   发生错误。

     

声明的局部变量的范围   在FormalParameter中的一部分   增强的for声明(§14.14)是   包含的声明

     

增强型for的含义   声明是通过翻译给出的   一个基本的for陈述。

     

如果 Expression 的类型是a   Iterable的子类型,然后让 I 成为   表达式的类型   表达。 iterator()。增强的for语句是等效的   到...的基本for陈述   形式:

for (I #i = Expression.iterator(); #i.hasNext(); ) {

        VariableModifiersopt Type Identifier = #i.next();
   Statement
}
     

#i 是编译器生成的   与任何不同的标识符   其他标识符(编译器生成的   或者在其他方面)在范围内(§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语句   发生。

因此,在您的情况下,genArray()不会返回Iterable的子类型,而是返回数组类型,因此增强的for语句等同于以下基本for语句:

String[] a = genArray();
...
for (int i = 0; i < a.length; i++) {
    String s = a[i];
    // ...
}

genArray()因此只会被调用一次(但目前接受的答案部分错误)。

答案 1 :(得分:5)

Java将调用genArray()一次,获取迭代器对象,并多次调用它。

答案 2 :(得分:5)

它应该只使用一次 - 它与调用它相同:

  String[] strings = genArray();
  for (String s : strings) {
  ...