Точно ли определен порядок итерации Java foreach для примитивов?

StackOverflow https://stackoverflow.com/questions/660097

  •  20-08-2019
  •  | 
  •  

Вопрос

Пример кода:

int a[] = new int[]{0, 1, 2, 3};
int result = 0;
for (int i : a)
    result += i;

Гарантируется ли повторение цикла через a[0], a[1], a[2], a[3] в таком порядке?Я твердо верю, что ответ - да, но эта страница похоже, не совсем однозначно излагается порядок.

Есть надежная рекомендация?

Это было полезно?

Решение

Согласно JLS, усовершенствованный for заявление, ваш цикл for эквивалентен

int[] array = a;
for (int index = 0; index < a.length; index++) {
    int i = array[index];
    result += i;
}

"где array и index являются сгенерированными компилятором идентификаторами, отличными от любых других идентификаторов (сгенерированных компилятором или иным образом), которые находятся в области видимости в точке, где расширенное for происходит утверждение ". (слегка перефразируя здесь имена переменных).

Так что да:заказ абсолютно гарантирован.

Другие советы

Видишь раздел 14.14.2 спецификации языка Java, 3-е издание.

Если тип выражения является подтипом Iterable , то пусть I будет типом выражения Expression.iterator().Расширенный оператор for эквивалентен базовому оператору for, имеющему вид:

for (I #i = Expression.iterator(); #i.hasNext(); ) {
        VariableModifiersopt Type Identifier = #i.next();
   Statement
}

Где #i - сгенерированный компилятором идентификатор, который отличается от любых других идентификаторов (сгенерированных компилятором или иным образом), которые находятся в области видимости (§6.3) в точке, где встречается оператор enhanced for .

В нем говорится , что в JLS это:

for ( VariableModifiersopt Type Identifier: Expression) Statement

эквивалентно

T[] a = Expression;
L1: L2: ... Lm:
for (int i = 0; i < a.length; i++) {
        VariableModifiersopt Type Identifier = a[i];
        Statement
}

Я не нашел на странице, на которую вы ссылались, ничего, что подразумевало бы неупорядоченную итерацию.Можете ли вы опубликовать конкретную цитату?

В любом случае, я нахожу, что этот код:

public static void main( String args[] ) {
    double a[] = new double[] { 0, 1, 2, 3 };
    int result = 0;
    for ( double i : a ) {
        result += i;
    }

декомпилирует до зацикливания в старом стиле:

 public static void main(String args[])
    {
        double a[] = {
            0.0D, 1.0D, 2D, 3D
        };
        int result = 0;
        double ad[];
        int k = (ad = a).length;
        for(int j = 0; j < k; j++)
        {
            double i = ad[j];
            result = (int)((double)result + i);
        }
    }

Конечно, это не то же самое, что гарантия, но, по крайней мере, неупорядоченная итерация по массиву была бы очень странной и, казалось бы, противоречила бы очевидной реализации здравого смысла.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top