2014-09-12 11 views
5

Mam następujący kod:Zaawansowana pętla Java: co jest (nie) oceniane w nagłówku pętli?

for (Attribute thisAttribute : factor.getAttributes()) { 
// blabla 
} 

gdzie factor.getAttributes() powraca List<Attribute>.

Prawdopodobnie istnieje tylko jedno początkowe połączenie z factor.getAttributes(), a następnie rozpoczyna się przejście. Jednak nie rozumiem, dlaczego jest tylko jedno połączenie. Gdybym miał dołączyć wywołanie funkcji do nagłówka regularnej pętli for(), sądzę, że byłby on oceniany w każdej iteracji. W związku z tym, w jaki sposób i dlaczego zaawansowana pętla jest inna?

+0

Dla każdej pętli jest bit inny dla normalnej pętli for. Musisz zrozumieć, że dla każdej pętli otrzymujemy kolekcję i używamy iteratora, aby ją pętli. – StackFlowed

+0

Skąd JVM wie, że mam zamiar pobrać kolekcję tylko raz na początku? – James

+2

Zależy od części głowicy pętli, o której mówisz, o tym, jak często coś jest wywoływane. W klasycznej pętli 'for (int i = getStartInt(); i ajp15243

Odpowiedz

7

myśleć o tym, jak coraz przetłumaczony na coś takiego:

{ 
    Iterator<Attribute> it = factor.getAttributes().iterator(); 
    while (it.hasNext()) { 
     Attribute thisAttribute = it.next(); 
     // loop body here 
    } 
} 

Kompilator wie, że dostaje iterable, może dostać iterator z nim raz i używać go w pętli.

Okazuje się, że Java language specification wydaje się zgodzić, to mówi:

Udoskonalony dla oświadczenia jest równoznaczne z podstawowym dla zestawienia w postaci:

for (I #i = Expression.iterator(); #i.hasNext();) { 
    {VariableModifier} TargetType Identifier = 
     (TargetType) #i.next(); 
    Statement 
} 
+3

Nitpicking: Nie powinno to być 'Iterator it = factor.getAttributes(). Terator();'? –

+2

Referencje JLS: http://docs.oracle.com/javase/specs/jls/se8/html/jls-14.html#jls-14.14.2 –

+0

@Aeshang: zatwierdzone, dziękuję. –

Powiązane problemy