Подтвердить что ты не робот

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

Пример кода:

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] в этом порядке? Я твердо верю, что ответ - да, но эта страница, кажется, не однозначно устанавливает порядок.

Есть надежная ссылка?

4b9b3361

Ответ 1

Согласно JLS, расширенный оператор for, ваш for-loop эквивалентен

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

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

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

Ответ 2

См. раздел 14.14.2 Спецификации Java Language, 3-е издание.

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

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

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

Ответ 3

В 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
}

Ответ 4

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

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

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);
        }
    }

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