2008-08-07 11 views
26

मैं जावा कल्पना की कमियों के संदर्भ में an answer to another question में यह देखा था,:क्या यह वास्तव में चौड़ा बनाम ऑटोबॉक्सिंग है?

अधिक कमियों रहे हैं और यह एक सूक्ष्म विषय है। this की जाँच करें:

public class methodOverloading{ 
    public static void hello(Integer x){ 
      System.out.println("Integer"); 
    } 

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

    public static void main(String[] args){ 
     int i = 5; 
     hello(i); 
    } 
} 

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

हम चाहते हैं कि यह वास्तव में autoboxing के बजाय चौड़ा करने का एक उदाहरण है, या यह कोई अन्य विषय कुछ है यकीन है?

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

hello(Long x) 

उत्पादन के लिए

hello(long x) 

बदल "Integer" प्रिंट होगा

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

+0

निश्चित रूप से यह चौड़ा हो रहा है। Int लंबे समय तक चौड़ा है। – EJP

उत्तर

12

पहले मामले में, आपके पास एक व्यापक रूपांतरण हो रहा है।

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, जो चौड़ा पूर्णांक-हैं- लिए स्मरक है देखें: यह जब "javap" उपयोगिता कार्यक्रम (w/JDK शामिल) runinng, संकलित वर्ग पर देख जा सकता है लंबे बाइटकोड निर्देश। संदर्भ here देखें।

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), रैपर के अंदर आदिम बॉक्स करने के लिए।

+5

मुझे लगता है कि यह स्पष्ट है कि जावा को ऑटो-मुक्केबाजी से पहले विस्तार करना है क्योंकि पुराना कोड चौड़ा होने पर निर्भर करता है और अगर वह कोड अचानक ऑटो-मुक्केबाजी में बदल जाता है तो टूट जाएगा। –

3

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

संपादित करें: the original post being referenced

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

1

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

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); 
} 

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

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

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