在java增强的for循环中,假设要循环的表达式仅被评估一次是否安全? [重复]

问题描述 投票:0回答:3

在Java中,使用for-each循环。我有一个生成数组的方法,称为

genArray()

在下面的代码中,每次迭代都会通过调用

genArray()
重新生成数组吗?或者 Java 会调用一次该方法并存储数组中的副本吗?

for (String s : genArray())
{
    //...
}
java arrays foreach iteration
3个回答
28
投票

关于增强的for语句,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()
因此只会被调用一次(但当前接受的答案部分错误)。


5
投票

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


5
投票

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

  String[] strings = genArray();
  for (String s : strings) {
  ...
© www.soinside.com 2019 - 2024. All rights reserved.