क्या यह वास्तव में चौड़ा बनाम autoboxing है?

मैंने Java spec की कमियों के संदर्भ में किसी अन्य प्रश्न का उत्तर में देखा:

और कमियां हैं और यह एक सूक्ष्म विषय है। यह देखें:

  पब्लिक क्लास विधि ओवरलोडिंग {
     सार्वजनिक स्थैतिक शून्य हैलो (इंटीजर एक्स) {
          Println ( "पूर्णांक");
     }

     सार्वजनिक स्थिर शून्य हैलो (लंबा एक्स) {
          Println ( "लंबे");
     }

     सार्वजनिक स्थैतिक शून्य main (String [] args){
         int i = 5;
         नमस्ते (i);
     }
}
 
     

यहां "लंबा" मुद्रित किया जाएगा (इसे स्वयं जांच नहीं लिया है), क्योंकि संकलक ऑटो-मुक्केबाजी पर चौड़ा चुनता है। ऑटो-मुक्केबाजी का उपयोग करते समय सावधान रहें या इसका उपयोग न करें!

क्या हमें यकीन है कि यह वास्तव में ऑटोबॉक्सिंग के बजाय चौड़ाई का एक उदाहरण है, या यह पूरी तरह से कुछ और है?

मेरे शुरुआती स्कैनिंग पर, मैं इस कथन से सहमत होगा कि आउटपुट i के आधार पर "लंबा" होगा जो कि आदिम के रूप में घोषित किया जा रहा है, न कि ऑब्जेक्ट। हालांकि, अगर आप बदल गए हैं

hello(long x)

सेवा मेरे

hello(Long x)

आउटपुट "इंटीजर" प्रिंट करेगा

वास्तव में यहाँ क्या चल रहा है? मैं जावा के लिए कंपाइलर्स / बाइटकोड दुभाषियों के बारे में कुछ भी नहीं जानता ...

0
ro fr bn
निश्चित रूप से यह चौड़ा हो रहा है। Int लंबे समय तक चौड़ा है।
जोड़ा लेखक EJP, स्रोत

3 उत्तर

हां यह है, इसे एक परीक्षण में आज़माएं। आप "लंबे" मुद्रित देखेंगे। यह चौड़ा हो रहा है क्योंकि जावा इंटीजर को ऑटोबॉक्स करने के लिए चुनने से पहले लंबे समय तक int को विस्तृत करने का विकल्प चुनता है, इसलिए हैलो (लंबी) विधि को कॉल करने के लिए चुना जाता है।

संपादित करें: मूल पोस्ट संदर्भित किया जा रहा है

आगे संपादित करें: दूसरे विकल्प को इंटीजर प्रिंट करने का कारण यह है कि एक विकल्प के रूप में एक बड़े आदिम में "चौड़ा" नहीं है, इसलिए इसे इसे बॉक्स करना होगा, इस प्रकार इंटीजर ही एकमात्र विकल्प है। इसके अलावा, जावा केवल मूल प्रकार के लिए ऑटोबॉक्स होगा, इसलिए यदि आप हैलो (लांग) छोड़ दें और हैलो (इंटीजर) हटा दें तो यह एक कंपाइलर त्रुटि देगा।

0
जोड़ा

पहले मामले में, आपके पास एक व्यापक रूपांतरण हो रहा है। यह तब देखा जा सकता है जब संकलित वर्ग पर "जावप" उपयोगिता प्रोग्राम (डब्ल्यू / जेडीके शामिल था) को चलाएं:

public static void main(java.lang.String[]);
  Code:
   0:   iconst_ 5
   1:   istore_ 1
   2:   iload_ 1
   3:   i2l
   4:   invokestatic    #6; //Method hello:(J)V
   7:   return

}

जाहिर है, आप I2L देखते हैं, जो व्यापक इंटीजर-टू-लांग बाइटकोड निर्देश के लिए स्मारक है। संदर्भ यहां देखें।

और दूसरे मामले में, "लांग एक्स" ऑब्जेक्ट के साथ "लांग एक्स" को प्रतिस्थापित करने के बाद, आपके पास यह विधि मुख्य विधि में होगी:

public static void main(java.lang.String[]);
  Code:
   0:   iconst_ 5
   1:   istore_ 1
   2:   iload_ 1
   3:   invokestatic    #6; //Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
   6:   invokestatic    #7; //Method hello:(Ljava/lang/Integer;)V
   9:   return

}

तो आप देखते हैं कि कंपाइलर ने रैपर के अंदर आदिम को बॉक्स करने के लिए निर्देश Integer.valueOf (int) बनाया है।

0
जोड़ा
मुझे लगता है कि यह स्पष्ट है कि जावा को ऑटो-मुक्केबाजी से पहले विस्तार करना है क्योंकि पुराना कोड चौड़ा होने पर निर्भर करता है और अगर वह कोड अचानक ऑटो-मुक्केबाजी में बदल जाता है तो टूट जाएगा।
जोड़ा लेखक Mr. Shiny and New 安宇, स्रोत

इस उदाहरण के साथ एक और दिलचस्प बात विधि अधिभार है। प्रकार चौड़ाई और विधि अधिभार केवल संयोजन का संयोजन क्योंकि संकलक को चुनने के लिए किस विधि का निर्णय लेना है। निम्नलिखित उदाहरण पर विचार करें:

public static void hello(Collection x){
   System.out.println("Collection");
}

public static void hello(List x){
   System.out.println("List");
}

public static void main(String[] args){
   Collection col = new ArrayList();
   hello(col);
}

यह रन-टाइम प्रकार का उपयोग नहीं करता है जो सूची है, यह संकलन-समय प्रकार का उपयोग करता है जो संग्रह है और इस प्रकार "संग्रह" प्रिंट करता है।

मैं आपको प्रभावी जावा पढ़ने के लिए प्रोत्साहित करता हूं, जिसने मेरी आंखों को कुछ कोने मामलों में खोला JLS।

0
जोड़ा