2013-08-01 4 views
12

के मामले में कॉल करने के लिए JVM विधि (निकटतम मिलान वाला पैरामीटर) कैसे पाता है JVM संकलित समय पर कॉल करने के लिए कौन सी अधिभारित विधि तय करता है। मैं एक उदाहरण है: अगर मैंफ़ंक्शन ओवरलोडिंग

takes int 
takes Long 
takes Short 

हालांकि: मेरी समझ के अनुसार

public class MainClass{ 

    public static void go(Long n) {System.out.println("takes Long ");} 
    public static void go(Short n) {System.out.println("takes Short ");} 
    public static void go(int n) {System.out.println("takes int ");} 

    public static void main(String [] args) { 
    short y = 6; 
    long z = 7; 
    go(y); 
    go(z); 
    go((Short)y); 
    } 
} 

, यह निम्न प्रिंट चाहिए:

takes Short 
takes Long 
takes Short 

... लेकिन वास्तविक उत्पादन होता है निम्नलिखित तीन कार्य:

public static void go(Integer n) {System.out.println("takes Integer");} 
public static void go(Long n) {System.out.println("takes Long ");} 
public static void go(Short n) {System.out.println("takes Short ");} 

... और यह का उपयोग कर फोन:

int a= 10; and go(i); //output : takes Integer. 

... क्यों है short और int के लिए एक अंतर है?

+0

http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.12.4 – kosa

+0

संभावित डुप्लिकेट http://stackoverflow.com/ क्यू/6268157/2087187 – EProgrammerNotFound

उत्तर

18

JLS Section 15.12.2, के लिए नियमों को संकलक निर्धारित करने के लिए कौन सी विधि आह्वान करने के लिए इस प्रकार देखें। संकलक हमेशा सबसे विशिष्ट विधि मामले में अपने तरीके अतिभारित रहे हैं चुनता है:

वहाँ एक से अधिक तरह के विधि, जिस स्थिति में सबसे विशिष्ट एक चुना जाता है हो सकता है। सबसे विशिष्ट विधि का वर्णनकर्ता (हस्ताक्षर प्लस रिटर्न प्रकार) विधि प्रेषण करने के लिए रन टाइम पर उपयोग किया जाता है।

पहले चरण (§15.12.2.2) अधिभार संकल्प करता मुक्केबाजी या unboxing रूपांतरण की अनुमति के बिना, या:

संकलक पहले मुक्केबाजी या unboxing बिना विधि को हल करने की कोशिश करता है के रूप में वहाँ उद्धृत परिवर्तनीय धैर्य विधि आवेषण का उपयोग। यदि इस चरण के दौरान कोई लागू विधि नहीं मिलती है तो प्रसंस्करण दूसरे चरण तक जारी रहता है।

जोर मेरा।

तो, अपने 1 सेंट कोड में, के बाद से कम प्रकार पूर्णांक के पैरामीटर के लिए तर्क के रूप में इस्तेमाल किया जा सकता।कंपाइलर पैरामीटर Short के साथ विधि का उपयोग नहीं करेगा, जिसके लिए मुक्केबाजी की आवश्यकता है। लंबे प्रकार के मामले में, क्योंकि इसे int टाइप करने के लिए तर्क के रूप में उपयोग नहीं किया जा सकता है, यह मुक्केबाजी के लिए Long पर जाता है। याद रखें बॉक्सिंग पर चौड़ाई को प्राथमिकता दी जाती है।

आपके 2 nd में, मुक्केबाजी int से Integer से कोई दूसरा रास्ता नहीं है। इसलिए, यह Integer पैरामीटर के साथ विधि कॉल करता है।

8

जेवीएम बिल्कुल नहीं मिला है। कंपाइलर करता है। यह सबसे विशिष्ट विधि को चुनता है, JLS section 15.12.2.5 में नियमों का पालन:

यदि एक से अधिक सदस्य विधि दोनों सुलभ और एक विधि मंगलाचरण के लिए लागू है, यह रन के लिए वर्णनकर्ता प्रदान करने के लिए एक का चयन करने के लिए आवश्यक है समय विधि प्रेषण। जावा प्रोग्रामिंग भाषा नियम का उपयोग करती है कि सबसे विशिष्ट विधि चुना जाता है।

अनौपचारिक अंतर्ज्ञान यह है कि एक विधि किसी अन्य से अधिक विशिष्ट होती है यदि पहली विधि द्वारा संचालित किसी भी आमंत्रण को किसी अन्य को संकलित-समय प्रकार त्रुटि के बिना पारित किया जा सकता है।

... (पूर्ण नियम) ...

+2

+1 न केवल नाम और पैरामीटर प्रकार सटीक मिलान होना चाहिए लेकिन वापसी का प्रकार भी होना चाहिए। यदि आप ए को कॉल करते हैं और आप ए को पुन: संकलित किए बिना बी में किसी विधि का रिटर्न प्रकार बदलते हैं, तो यह रनटाइम पर विधि ढूंढने में विफल हो जाएगा। –

1

क्योंकि int का उत्थान जावा के संस्करण 1.0 में था और ऑटो-मुक्केबाजी संस्करण 5.0 में जोड़ा गया था। व्यवहार को बदलने से जावा के पुराने संस्करण के लिए कोड लिखा जाएगा।

+0

यह "उछाल" नहीं है --- यह एक "चौड़ा रूपांतरण" है। लेकिन अन्यथा एक अच्छा बिंदु, +1। –

+1

@MarkoTopolnik। खैर उत्तर इस प्रश्न के लिए पोस्ट किए गए डुप्लिकेट से स्वीकृत उत्तर की एक कॉपी पेस्ट लगता है। तो, गलती * स्रोत * में है। lol;) –

+0

@ रोहितजैन ओह, यह जांचने के लिए धन्यवाद! और हम जानते हैं कि चोरी चोरी क्या है ... –

0

मुक्केबाजी (यदि कोई हो) से पहले चौड़ा होता है। तो shortint बन जाएगा और उन विधियों को कॉल करें।

इसके अलावा, सीधे इस सवाल लेकिन दिलचस्प बात के साथ प्रासंगिक नहीं: आप बॉक्स नहीं कर सकते और चौड़ा अर्थात shortInteger

0

जावा पहले करीबी मिलान के लिए लग रहा है नहीं बन सकता है। यह निम्न खोजने की कोशिश करता: प्रकार

  • एक सुपर वर्ग प्रकार
  • एक बड़ा आदिम प्रकार
  • एक ऑटो बॉक्सिंग प्रकार
  • varargs में कनवर्ट कर रहा करने के लिए परिवर्तित मिलान द्वारा

    1. सटीक मिलान
  • 0

    नीचे दिया गया वीडियो स्पष्ट रूप से बताता है कि विधि ओवरलोडिंग के मामले में JVM विभिन्न योग्य तरीकों के बीच एक विधि का चयन कैसे करता है।

    https://www.youtube.com/watch?v=P4XtP1aeI3g

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