2010-12-30 12 views
7
String[] strs = new String[] { "1", "2", ... , "6" }; 

for (String s : strs) { 
    System.out.println(s); 
} 

यह जावा आंतरिक के बारे में एक प्रश्न है।जावा कैसे पता चलता है कि एरे को कैसे घुमाया जाए

उपर्युक्त कोड नमूने में, फ़ोरैच लूप कैसे पता लगाता है कि सरणी कितनी देर तक है? क्या सरणी वास्तव में आंतरिक रूप से ऑब्जेक्ट करती हैं या क्या यह sizeof जैसी सामग्री का उपयोग कर रही है जो फ्रंट एंड प्रोग्रामर के लिए पहुंच योग्य नहीं है?

मुझे एहसास है कि मुझे बस कुछ बेवकूफ याद आ रही है, लेकिन मुझे लगता है कि यह भी ठंडा हो सकता है। :-)

+0

संभावित डुप्लिकेट [प्रत्येक लूप के लिए जावा कैसे काम करता है?] (Http://stackoverflow.com/questions/85190/how-does-the-java-for-each-loop-work) –

+1

+1 दिलचस्प सवाल, और एक डुप्लिकेट पर नहीं। –

+0

काफी नहीं। मुझे पहले से ही पता है कि यह पुनरावृत्त है, लेकिन पुनरावृत्ति को कब रोकना है? – SapphireSun

उत्तर

11

मैं निम्नलिखित कोड संकलित:

public class ArrayIterator 
{ 
    public static void main(String[] argv) 
    { 
     String[] strs = new String[] { "1", "2", "3", "4", "5" }; 
     enhancedPrint(strs); 
     normalPrint(strs); 
    } 

    public static void enhancedPrint(String[] strs) 
    { 
     for (String s : strs) 
     { 
      System.out.println(s); 
     } 
    } 

    public static void normalPrint(String[] strs) 
    { 
     String[] localArray = strs; 
     int len = localArray.length; 
     for (int i = 0; i < len; i++) 
     { 
      String s = localArray[i]; 
      System.out.println(s); 
     } 
    } 
} 

यह disassembled (javap -c ArrayIterator) बार-बार दोहराना कार्यों के लिए बाईटकोड है:

बढ़ाया प्रिंट:

public static void enhancedPrint(java.lang.String[]); 
    Code: 
    0: aload_0 
    1: astore_1 
    2: aload_1 
    3: arraylength 
    4: istore_2 
    5: iconst_0 
    6: istore_3 
    7: iload_3 
    8: iload_2 
    9: if_icmpge 31 
    12: aload_1 
    13: iload_3 
    14: aaload 
    15: astore 4 
    17: getstatic #10; //Field java/lang/System.out:Ljava/io/PrintStream; 
    20: aload 4 
    22: invokevirtual #11; //Method java/io/PrintStream.println:(Ljava/lang/String;)V 
    25: iinc 3, 1 
    28: goto 7 
    31: return 

पाश के लिए एक सामान्य:

public static void normalPrint(java.lang.String[]); 
    Code: 
    0: aload_0 
    1: astore_1 
    2: aload_1 
    3: arraylength 
    4: istore_2 
    5: iconst_0 
    6: istore_3 
    7: iload_3 
    8: iload_2 
    9: if_icmpge 31 
    12: aload_1 
    13: iload_3 
    14: aaload 
    15: astore 4 
    17: getstatic #10; //Field java/lang/System.out:Ljava/io/PrintStream; 
    20: aload 4 
    22: invokevirtual #11; //Method java/io/PrintStream.println:(Ljava/lang/String;)V 
    25: iinc 3, 1 
    28: goto 7 
    31: return 

आप देख सकते हैं, दोनों ही मामलों में, संकलक सरणियों लंबाई (strs.length) लोड हो रहा है और इसके खिलाफ पाशन है। हम देखते हैं कि प्रत्येक लूप के लिए बढ़ाया गया है, एक ऐरे के मामले में सरणी की लंबाई के खिलाफ लूपिंग के लिए सिंटैक्टिक चीनी है (ऑब्जेक्ट के मामले में जहां यह एक इटरेटर का उपयोग करता है)।


मैं पाश के लिए 'सामान्य' संपादित किया है ऐसी है कि वह बहुत कम मुहावरेदार है, लेकिन यह पाश के लिए बढ़ाया रूप में एक ही बाईटकोड है। सभी उद्देश्यों और उद्देश्यों के लिए, लूप संस्करण के लिए सामान्य वह है जो संकलक उत्पन्न करता है जब यह प्रत्येक लूप के लिए बढ़ाया जाता है।

+0

वाह! आपका बहुत बहुत धन्यवाद! – SapphireSun

3

हाँ, वहाँ सी ++ sizeof ऑपरेटर के सदृश कुछ है - यह length उदाहरण चर है length क्षेत्र (जो सरणी, नहीं बाइट में आकार में तत्वों की संख्या देता है।) हमेशा सरणी का एक सार्वजनिक सदस्य होता है, इसलिए यह जावा प्रोग्रामर के लिए सुलभ है।

और हाँ, सरणी objects हैं, न केवल आंतरिक रूप से।

(अधिक मोटे तौर पर, for पाश वाक्य रचना question से जुड़ी org.life.java में वर्णित के रूप में काम करता है, लेकिन यह है कि काफी है कि तुम क्या पूछ रहे थे नहीं है।)

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