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

Mar*_*aux 10 java arrays iteration foreach

在Java中,for-each循环.
如果我有一个生成数组的方法,则调用genArray().

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

for (String s : genArray())
{
    //...
}
Run Code Online (Sandbox Code Playgroud)

谢谢

Pas*_*ent 23

关于增强的for语句,Java语言规范写道:

增强的for语句具有以下形式:

EnhancedForStatement:
        for ( VariableModifiersopt Type Identifier: Expression) Statement
Run Code Online (Sandbox Code Playgroud)

Expression必须具有类型 Iterable,否则它必须是数组类型(第10.1节),否则会发生编译时错误.

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

增强for 陈述的含义通过翻译成基本for陈述给出.

如果类型Expression是子类型Iterable,那么让我们I成为表达式Expression的类型 .iterator().增强for语句等同于for表单的基本语句:

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

        VariableModifiersopt Type Identifier = #i.next();
   Statement
}
Run Code Online (Sandbox Code Playgroud)

#i编译器生成的标识符在何处是与增强的for语句发生时的范围(第6.3节)中的任何其他标识符(编译器生成的或其他标识符)不同.

否则,Expression必须具有数组类型,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
}
Run Code Online (Sandbox Code Playgroud)

其中ai是编译器生成的标识符,它们与发生增强for语句的范围内的任何其他标识符(编译器生成的或其他标识符)不同.

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

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

并且genArray()将因此被称为只有一次(但目前公认的答案是部分错误的).


Joh*_*fer 5

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

  • 这个答案部分是错误的**.是的,Java只会调用`genArray()`一次,但是,不,`java.lang.Array`不是`Iterable'的子类型,所以Java不会得到迭代器对象. (5认同)

mat*_*att 5

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

  String[] strings = genArray();
  for (String s : strings) {
  ...
Run Code Online (Sandbox Code Playgroud)