É Java foreach ordem de iteração mais primitivos definidos precisamente?
Pergunta
código Exemplo:
int a[] = new int[]{0, 1, 2, 3};
int result = 0;
for (int i : a)
result += i;
É o loop garantido para iterate através a[0]
, a[1]
, a[2]
, a[3]
nessa ordem? Eu acredito fortemente que a resposta é sim, mas esta página parece ordem estatal não de forma inequívoca.
Got uma referência sólida?
Solução
De acordo com a os JLS, a declaração for
reforçada , o seu ciclo for é equivalente a
int[] array = a;
for (int index = 0; index < a.length; index++) {
int i = array[index];
result += i;
}
"onde array
e index
identificadores são gerados pelo compilador que são distintos de quaisquer outros identificadores (compilador-gerado ou de outro modo) que estão no escopo no ponto em que a instrução for
melhorada ocorre." (Ligeiramente parafraseando os nomes das variáveis ??aqui).
Então, sim:. A ordem é absolutamente garantido
Outras dicas
seção 14.14.2 da especificação de linguagem Java , 3ª edição .
Se o tipo de expressão é um subtipo de Iterable, então deixe eu ser o tipo de o Expression.iterator expressão (). A instrução for aprimorada é equivalente a um básico para a declaração de a forma:
for (I #i = Expression.iterator(); #i.hasNext(); ) { VariableModifiersopt Type Identifier = #i.next(); Statement }
Onde #i é um compilador-gerado identificador que é distinto de qualquer outros identificadores (compilador-gerado ou de outro modo) que estão dentro do escopo (§6.3) no ponto em que o reforço do declaração ocorre.
Ele afirma na JLS que:
for ( VariableModifiersopt Type Identifier: Expression) Statement
é equivalente a
T[] a = Expression;
L1: L2: ... Lm:
for (int i = 0; i < a.length; i++) {
VariableModifiersopt Type Identifier = a[i];
Statement
}
Eu não encontrar qualquer coisa na página que você já referenciado que implicaria iteração fora-de-ordem. você pode enviar a citação específica?
Em qualquer caso, eu acho que este código:
public static void main( String args[] ) {
double a[] = new double[] { 0, 1, 2, 3 };
int result = 0;
for ( double i : a ) {
result += i;
}
decompiles ao velho estilo loop:
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);
}
}
É claro, isso não é o mesmo que uma garantia, mas na iteração muito menos fora-de-ordem sobre uma série seria muito estranho e parece ir contra a implementação de senso comum óbvio.