2009-03-18 7 views
25

Пример кода:Является ли 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] в таком порядке? Я твердо верю, что ответ «да», но this page, кажется, не однозначно заявляет порядок.

Получил твердую ссылку?

ответ

46

Согласно the JLS, The enhanced for statement, вашему для цикла эквивалентен

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

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

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

1

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

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

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

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

+1

Это может быть быстрее, чтобы разделить элементы и нити петлю. Некоторые компиляторы уже разворачивают и векторизовать петли, выполняя математику. Это не по порядку. Потоки могли быть следующим. –

7

См. section 14.14.2 of the Java Language Specification, 3rd edition.

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

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

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

5

Он утверждает в 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 
} 
+1

Для тех, кто смущен/незнакомец, поскольку я был синтаксисом метки «L1: L2: ... Lm», см. Http: // stackoverflow.ком/вопросы/2710422/пожалуйста, объясни-на-использование-на-меченных-выписки – cellepo

 Смежные вопросы

  • Нет связанных вопросов^_^