【问题标题】:In a java enhanced for loop, is it safe to assume the expression to be looped over will be evaluated only once?在 java 增强的 for 循环中,假设要循环的表达式只计算一次是否安全?
【发布时间】:2010-12-09 17:53:58
【问题描述】:

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

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

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

谢谢

【问题讨论】:

  • 当然,最简单的方法就是测试一下... genArray() 中的一个简单的 System.out.println() 就足够了!
  • Java foreach efficiency 的可能重复项

标签: java arrays foreach iteration


【解决方案1】:

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

增强的 for 语句具有 形式:

EnhancedForStatement:
        for ( VariableModifiersopt Type Identifier: Expression) Statement

表达式必须具有类型 Iterable 否则它必须是 数组类型(§10.1),或编译时 发生错误。

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

增强for的含义 声明是通过翻译成 一个基本的for 声明。

如果 Expression 的类型是 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
}

ai 是编译器生成的 不同于任何标识符的标识符 其他标识符(编译器生成的 或其他)在范围内 增强 for 语句的点 发生。

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

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

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • 这个答案部分错误。是的,Java 只会调用一次 genArray(),但是,不,java.lang.Array 不是 Iterable 的子类型,因此 Java 不会获得迭代器对象。
    【解决方案3】:

    它应该只被使用一次——它和调用这个是一样的:

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

    【讨论】:

      猜你喜欢
      • 2011-11-08
      • 1970-01-01
      • 1970-01-01
      • 2011-01-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多