2009-10-24 12 views
8

W języku Java: pętla for-each.
Jeśli mam metodę, która generuje tablicę, o nazwie genArray().W pętli rozszerzonej java, czy można założyć, że wyrażenie, które ma zostać zapętlone, zostanie ocenione tylko raz?

W poniższym kodzie, tablica będzie każdorazowo ponownie generowane przez wywołanie genArray()? Czy wywoła Java po metodzie i zachowa kopię z tablicy?

for (String s : genArray()) 
{ 
    //... 
} 

Dzięki

+3

Oczywiście najłatwiej jest sprawdzić, czy ... Wystarczy prosty System.out.println() w funkcji genArray()! – PhiLho

+0

możliwy duplikat [wydajność foreach Java] (http://stackoverflow.com/questions/904582/java-foreach-efficiency) –

Odpowiedz

23

O the enhanced for statement, języka Java Specyfikacja pisze:

Udoskonalona na rachunku ma forma:

EnhancedForStatement: 
     for (VariableModifiersopt Type Identifier: Expression) Statement 

Wyrażenie musi mieć typ Iterable albo musi być typu Array (§10.1), lub w czasie kompilacji błędu.

Zakres zmiennej lokalnej oświadczył w części FormalParameter wystąpienia wzmocnione for rachunku (§14.14) jest zawarty komunikat

Znaczenie zwiększonej for rachunku jest podany przez tłumaczeniem na się podstawowe oświadczenie for.

Jeżeli rodzaj Expression jest podtyp Iterable, pozwól I być rodzaju ekspresji ekspresji.iterator(). Udoskonalony for zestawienie odpowiada do podstawowego for instrukcji postaci :

for (I #i = Expression.iterator(); #i.hasNext();) { 

     VariableModifiersopt Type Identifier = #i.next(); 
    Statement 
} 

przypadku #i jest kompilator generowane identyfikatorem, który różni się od wszelkich innych identyfikatorów (kompilator generowane lub inaczej), które są w zakresie (§ 6.3) w punkcie, w którym występuje rozszerzone dla oświadczenie.

W przeciwnym razie wyrażenie musi koniecznie ma typ tablicy, T[].Niech to jest (prawdopodobnie pusta) sekwencja etykiet o długości bezpośrednio poprzedzającej wyciągnięcie z . Następnie sens zwiększona do rachunku oblicza się według następującego podstawowego for stwierdzeniem:

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

Gdzie i i są kompilatora generowane identyfikatory, które są odmienne od wszelkich innych identyfikatorów (wygenerowany przez kompilator: lub inny), które znajdują się w zakresie w punkcie , w którym występuje rozszerzone dla instrukcji .

Więc w twoim przypadku, genArray() nie zwraca podtyp Iterable ale typ tablicy, dzięki czemu zwiększona for stwierdzenie jest równoznaczne z następującym oświadczeniem: podstawowej for

String[] a = genArray(); 
... 
for (int i = 0; i < a.length; i++) { 
    String s = a[i]; 
    // ... 
} 

I genArray() będzie zatem być wywołanym tylko raz (ale aktualnie zaakceptowana odpowiedź jest częściowo błędna).

5

Java wezwie genArray() raz, uzyskać obiektu iteracyjnej i nazywają to wiele razy.

+5

Ta odpowiedź jest częściowo błędna **. Tak, Java wywoła funkcję 'genArray()' tylko raz, ale nie, 'java.lang.Array' nie jest podtypem' Iterable', więc Java nie otrzyma obiektu iteratora. –

5

Należy przyzwyczaić się tylko raz - to samo jak wywołanie to:

String[] strings = genArray(); 
    for (String s : strings) { 
    ... 
Powiązane problemy