2009-10-24 20 views
8

Java'da, her bir döngü için.
genArray() adı verilen bir dizi üreten bir yöntem varsa.Bir döngü için geliştirilmiş bir java'da, döngülenecek ifadenin yalnızca bir kez değerlendirileceğini varsaymak güvenli midir?

Aşağıdaki kodda, dizi her seferinde genArray() numaralı telefonu arayarak yeniden üretilecek mi? Veya Java bir kez yöntemini çağırır ve diziden bir kopyasını saklar mı?

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

Teşekkür

+3

Elbette, bilmenin en kolay yolu test etmektir ... genArray() 'da basit bir System.out.println() yeterlidir! – PhiLho

+0

[Java foreach verimliliği] 'nin olası bir kopyası (http://stackoverflow.com/questions/904582/java-foreach-efficiency) –

cevap

23

Hakkında the enhanced for statement Java Dil Özellikleri yazıyor:

deyimi için bulunduğu geliştirilmiş formu:

EnhancedForStatement: 
     for (VariableModifiersopt Type Identifier: Expression) Statement 

İfadenintipinde olması gerekir. 10 Iterable veya başka bir dizi türü (§10.1) olmalıdır, veya bir derleme zamanı hata oluşuyor.

yerel değişkenin kapsamı bir geliştirilmiş for deyimi (§14.14) ait FormalParameter kısmında ilan bir tercüme verilir içerdiği Tablosu

geliştirilmiş for ifadenin anlamı olduğunu temel for bildirimi. Expression tipi Iterable bir alt tipi ise

, daha sonra I sentezleme İfade tipi olsun.iterator(). Geliştirilmiş for ifadesi biçimde bir bazik for açıklamaya eşdeğerdir: #i herhangi başka künyeleri (farklı olan bir derleyici tarafından oluşturulan tanımlayıcıdır

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

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

derleyici tarafından oluşturulan veya başka) kapsamındaki (§6.3) bildirimi için geliştirilmiş olan noktada.

Aksi takdirde, ifade zorunlu bir dizi türü, T[] sahiptir.geliştirilmiş for bildiriminin hemen öncesindeki etiketlerinin (muhtemelen boş) sırasını olsun. Daha sonra açıklamada için geliştirilmiş bir anlamı aşağıdaki temel for deyimi ile verilir:

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

nerede bir ve i herhangi diğer tanımlayıcılar ayrıdır derleyici tarafından oluşturulan tanımlayıcıları (vardır kapsamındaki kapsamda bulunan derleyici tarafından oluşturulan veya başka bir deyişle, bildirimi için geliştirilmiş. senin durumunda Yani

, genArray() Iterable bir alt türü ancak bir dizi yazın dönmez, bu nedenle gelişmiş for açıklamada aşağıdaki temel for deyimi eşdeğerdir:

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

Ve genArray() olacak böylece sadece bir kez çağrılabilir (ancak şu anda kabul edilen cevap kısmen yanlıştır).

5

Java, bir kez() genArray çağrı yineleyici nesne almak ve bunu birçok kez arayacak.

+5

Bu cevap kısmen ** yanlış **. Evet, Java 'genArray()' ı sadece bir kez çağırır, fakat hayır, 'java.lang.Array'' İterable' nin bir alt türü değildir, bu yüzden Java bir iterator nesnesi alamaz. –

5

Sadece bir kez alışmalıyız - bu çağırarak aynıdır:

String[] strings = genArray(); 
    for (String s : strings) { 
    ...