2009-10-24 13 views
8

जावा में, प्रत्येक लूप के लिए।
यदि मेरे पास कोई तरीका है जो एक सरणी उत्पन्न करता है, जिसे genArray() कहा जाता है।लूप के लिए बढ़ाए गए जावा में, क्या यह अभिव्यक्ति करने के लिए सुरक्षित है कि लूप किए जाने वाले अभिव्यक्ति का मूल्यांकन केवल एक बार किया जाएगा?

निम्नलिखित कोड में, प्रत्येक बार सरणी को genArray() पर कॉल करके पुन: उत्पन्न किया जाएगा? या जावा एक बार विधि को कॉल करेगा और सरणी से एक प्रति स्टोर करेगा?

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

धन्यवाद

+3

बेशक, यह जानने का सबसे आसान तरीका है कि परीक्षण करना ... genarray() में एक साधारण System.out.println() पर्याप्त है! – PhiLho

+0

[जावा फोरच दक्षता] के संभावित डुप्लिकेट (http://stackoverflow.com/questions/904582/java-foreach- क्षमता) –

उत्तर

23

बारे the enhanced for statement, जावा भाषा के विनिर्देशों के लेखन:

बयान के लिए बढ़ाया है प्रपत्र:

EnhancedForStatement: 
     for (VariableModifiersopt Type Identifier: Expression) Statement 

अभिव्यक्ति के पास या तोहोना चाहिए 10 Iterable या अन्यथा यह सरणी प्रकार (§10.1), या एक संकलन-समय त्रुटि होनी चाहिए।

एक स्थानीय चर का दायरा एक बढ़ाया for बयान (§14.14) की FormalParameter भाग में घोषित निहित वक्तव्य

बढ़ाया for बयान का अर्थ एक में अनुवाद द्वारा दिया जाता है है मूल for कथन।

Expression के प्रकार Iterable के उपप्रकार है, तो I हो अभिव्यक्ति अभिव्यक्ति के प्रकार करते हैं।iterator()। बढ़ाया for बयान बराबर प्रपत्र की एक बुनियादी for बयान के लिए है:

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

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

कहाँ #i एक संकलक-उत्पन्न पहचानकर्ता है कि किसी भी अन्य पहचानकर्ता (से अलग है है संकलक उत्पन्न या अन्यथा) जो उस बिंदु पर स्कोप (§6.3) में हैं जहां कथन के लिए बढ़ाया गया है।

अन्यथा, अभिव्यक्ति जरूरी एक सरणी प्रकार, T[] है।L1 ... Lm के से पहले for कथन से पहले (संभावित रूप से खाली) अनुक्रम (संभवतः खाली) अनुक्रम दें। फिर बयान के लिए बढ़ाया का अर्थ निम्न बुनियादी for बयान द्वारा दिया जाता है:

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

कहाँ एक और मैं संकलक उत्पन्न पहचानकर्ता है कि किसी भी अन्य पहचानकर्ता से भिन्न होता है (हैं संकलक-उत्पन्न या अन्यथा) जो बिंदु पर दायरे में हैं जहां कथन के लिए बढ़ाया गया है।

अपने मामले में

तो, genArray()Iterable की एक उप-प्रकार लेकिन एक सरणी प्रकार वापस नहीं करता है, तो अपनी बढ़ाया for बयान निम्न बुनियादी for बयान के बराबर है:

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

और genArray() होगा इस प्रकार केवल एक बार बुलाया जाना चाहिए (लेकिन वर्तमान में स्वीकृत उत्तर आंशिक रूप से गलत है)।

5

जावा() एक बार, genArray फोन इटरेटर वस्तु मिलता है, और फोन है कि कई बार होगा।

+5

यह उत्तर आंशिक रूप से ** गलत ** है। हां, जावा केवल 'genArray()' को कॉल करेगा, लेकिन नहीं, 'java.lang.Array' 'Iterable' का उप-प्रकार नहीं है, इसलिए जावा को इटेटरेटर ऑब्जेक्ट नहीं मिलेगा। –

5

यह केवल एक बार इस्तेमाल किया जाना चाहिए - यह इस कॉल करने जैसा ही है:

String[] strings = genArray(); 
    for (String s : strings) { 
    ... 
संबंधित मुद्दे