2010-04-21 6 views
13

निम्नलिखित में:लूप के लिए बढ़ाए गए जावा में, क्या यह अभिव्यक्ति करने के लिए सुरक्षित है कि लूप किए जाने वाले अभिव्यक्ति का मूल्यांकन केवल एक बार किया जाएगा?

for (String deviceNetwork : deviceOrganizer.getNetworkTypes(deviceManufacturer)) { 
    // do something 
} 

यह मान लेना कि deviceOrganizer.getNetworkTypes (deviceManufacturer) केवल एक बार कहा जाएगा सुरक्षित है?

+3

मैं ईमानदारी से आशा करता हूं, अन्यथा मेरे पास फिर से लिखने के लिए बहुत सारे कोड हैं ... – skaffman

+0

http://stackoverflow.com/questions/1618202/java-foreach-loop –

+3

@ पास्कल थिएंट - हां, लेकिन मेरा शीर्षक बेहतर है :) – morgancodes

उत्तर

18

हां, बिल्कुल।

section 14.14.2 of the spec से:

तो अभिव्यक्ति के प्रकार Iterable की एक उप-प्रकार है, तो मैं अभिव्यक्ति Expression.iterator() के प्रकार के हो सकते हैं। बयान के लिए बढ़ाया फार्म के बयान के लिए एक बुनियादी के बराबर है: (। सरणियों के साथ वैकल्पिक सौदों)

for (I #i = Expression.iterator(); #i.hasNext();) { 
     VariableModifiersopt Type Identifier = #i.next(); 
    Statement 
} 

नोट कैसे Expression केवल के लिए के पहले भाग में बताया गया है लूप अभिव्यक्ति - तो यह केवल एक बार मूल्यांकन किया जाता है।

7

हाँ, इसे आजमाइए:

public class ForLoop { 
    public static void main(String [] args) { 
     for(int i : testData()){ 
      System.out.println(i); 
     } 
    } 
    public static int[] testData() { 
     System.out.println("Test data invoked"); 
     return new int[]{1,2,3,4}; 
    } 
} 

आउटपुट:

$ java ForLoop 
Test data invoked 
1 
2 
3 
4 
1

पूरक क्या कहा गया है और सत्यापित करें कि कल्पना कर रहा है कि वह क्या कहते हैं करने के लिए, के लिए उत्पन्न बाईटकोड को देखो निम्न श्रेणी, जो विधि कॉल द्वारा लौटाई गई सूची में लूप करने के लिए पुरानी और नई स्टाइल लूप लागू करती है, getList():

public class Main { 
    static java.util.List getList() { return new java.util.ArrayList(); } 
    public static void main(String[] args) { 
     for (Object o : getList()) { 
      System.out.print(o); 
     } 
     for (java.util.Iterator itr = getList().iterator(); itr.hasNext();) { 
      Object o = itr.next(); System.out.print(o); 
     } 
    } 
} 

उत्पादन के प्रासंगिक भागों:

0: invokestatic #4; //Method getList 
    3: invokeinterface #5, 1; //InterfaceMethod java/util/List.iterator 
    8: astore_1 
    9: aload_1 
    10: invokeinterface #6, 1; //InterfaceMethod java/util/Iterator.hasNext 
    15: ifeq 35 
    18: aload_1 
    19: invokeinterface #7, 1; //InterfaceMethod java/util/Iterator.next 
    24: astore_2 
    25: getstatic #8; //Field java/lang/System.out 
    28: aload_2 
    29: invokevirtual #9; //Method java/io/PrintStream.print 
    32: goto 9 
    35: invokestatic #4; //Method getList 
    38: invokeinterface #10, 1; //InterfaceMethod java/util/List.iterator 
    43: astore_1 
    44: aload_1 
    45: invokeinterface #6, 1; //InterfaceMethod java/util/Iterator.hasNext 
    50: ifeq 70 
    53: aload_1 
    54: invokeinterface #7, 1; //InterfaceMethod java/util/Iterator.next 
    59: astore_2 
    60: getstatic #8; //Field java/lang/System.out 
    63: aload_2 
    64: invokevirtual #9; //Method java/io/PrintStream.print 
    67: goto 44 
    70: return 

यह दिखाता है कि पहले पाश (32 करने के लिए 0) और दूसरा (35-67) समान हैं।
उत्पन्न बाइटकोड बिल्कुल है।

+2

ओह मैन ... क्या हमें ** बाइटकोड देखना है? क्या हम सिर्फ जेएलएस द्वारा निर्दिष्ट नहीं कर सकते हैं? –

+0

एलओएल धन्यवाद स्टीफन, ठीक वही मैं क्या सोच रहा था। ओपी को टक्कर नहीं देना है, लेकिन मेरी राय में बाइटकोड इस उदाहरण में उसकी मदद नहीं कर सकता है –

संबंधित मुद्दे