2015-06-01 4 views
6
public class Test 
{ 
    public static void printValue(int i, int j, int k) 
    { 
     System.out.println("int"); 
    } 

    public static void printValue(byte...b) 
    { 
     System.out.println("long"); 
    } 

    public static void main(String... args) 
    { 
     byte b = 9; 
     printValue(b,b,b); 
    } 
} 

उपरोक्त कोड का आउटपुट "int" है। लेकिन यह "लंबा" होना चाहिए क्योंकि बाइट प्रकार तर्क फ़ंक्शन पहले से मौजूद है। लेकिन यहां कार्यक्रम बाइट मूल्यों को int में बढ़ावा दे रहा है, लेकिन यह मामला नहीं होना चाहिए।ओवरलोडेड विधियों के लिए वैरगास पर टाइप-प्रमोशन प्राथमिकता क्यों लेता है

कृपया कोई स्पष्ट कर सकते हैं यहाँ क्या चल रहा है?

+2

कृपया किसी पोस्ट में कोड सहित दस्तावेज़ को पढ़ें, और यह जांचने के लिए पूर्वावलोकन का उपयोग करें कि यह आपके पोस्ट करने से पहले उचित दिखता है। –

उत्तर

2

चर तर्क तरीकों हमेशा पिछले एक अतिभारित तरीकों के मामले में संकलक द्वारा चुने जाने के लिए किया जाएगा। एक byte को int (चौड़ाई-रूपांतरण) के प्रचार को उस विधि पर प्राथमिकता दी जाएगी जो एक var-arg पैरामीटर लेता है।

इसके पीछे कारण यह है कि भाषा पिछड़े संगत होना जरूरत है। पुरानी विशेषताएं नई सुविधाओं पर प्राथमिकता लेगी। समझने का एक आसान तरीका JLS वैरिएबल तर्कों के बारे में कहता है कि चौड़ा मुक्केबाजी मुकाबला करेगा और मुक्केबाजी विभिन्न-बहनों को हरा देगा।

10

JLS 15.12.2 कल्पना के प्रासंगिक बिट यहाँ को देखने के लिए है। विशेष रूप से - जोर मेरा:

जावा एसई 5.0 से पहले जावा प्रोग्रामिंग भाषा के संस्करणों के साथ संगतता सुनिश्चित करने के लिए प्रक्रिया का शेष तीन चरणों में विभाजित किया गया है। चरण होते हैं:

  • पहले चरण (§15.12.2.2) अधिभार संकल्प मुक्केबाजी या unboxing रूपांतरण या वैरिएबल arity विधि मंगलाचरण के उपयोग की अनुमति के बिना निष्पादित करता है। यदि इस चरण के दौरान कोई लागू विधि नहीं मिलती है तो प्रसंस्करण दूसरे चरण तक जारी रहता है।

    यह गारंटी देता है कि जावा एसई 5.0 से पहले जावा प्रोग्रामिंग भाषा में मान्य कोई भी कॉल वैरिएबल आर्टी विधियों, निहित मुक्केबाजी और/या अनबॉक्सिंग के परिचय के परिणामस्वरूप संदिग्ध नहीं माना जाता है। हालांकि, एक परिवर्तनीय धैर्य विधि (§8.4.1) की घोषणा किसी दिए गए विधि विधि आमंत्रण अभिव्यक्ति के लिए चुनी गई विधि को बदल सकती है, क्योंकि पहले चरण में एक परिवर्तनीय धैर्य विधि को निश्चित धर्मार्थ विधि के रूप में माना जाता है। उदाहरण के लिए, m(Object...) को एक कक्षा में घोषित करना जो पहले से ही m(Object) घोषित करता है m(Object) को अब कुछ आमंत्रण अभिव्यक्तियों (जैसे m(null)) के लिए चुना जाना नहीं है, m(Object[]) अधिक विशिष्ट है।

  • दूसरा चरण (§15.12.2.3) बॉक्सिंग और अनबॉक्सिंग की अनुमति देते हुए ओवरलोड रिज़ॉल्यूशन करता है, लेकिन फिर भी परिवर्तनीय धैर्य विधि आमंत्रण के उपयोग को रोकता है। यदि इस चरण के दौरान कोई लागू विधि नहीं मिलती है तो प्रसंस्करण तीसरे चरण तक जारी रहता है।

    यह सुनिश्चित करता है कि एक विधि चर arity विधि मंगलाचरण के माध्यम से अगर यह तय arity विधि मंगलाचरण के माध्यम से लागू होता है कभी नहीं चुना जाता है।

  • तीसरा चरण (§15.12.2.4) परिवर्तनीय धर्मार्थ विधियों, मुक्केबाजी और अनबॉक्सिंग के साथ ओवरलोडिंग को अनुमति देता है।

आपके मामले में, पहले चरण चर arity विधि मंगलाचरण या बॉक्सिंग का उपयोग किए बिना एक मैच पाता है, इसलिए है कि परिणाम है। जैसा कि स्पेक में उल्लेख किया गया है, यह मूल रूप से पिछड़े संगतता के लिए है।

+0

बहुत बहुत धन्यवाद जॉन। यह मेरे संदेह को स्पष्ट करता है। लेकिन, मुझे तीसरा चरण नहीं मिला। –

+1

@ShipraVarshney आप एक सरल समझ के लिए मेरे जवाब पर एक नज़र डाल सकते हैं। – CKing

+0

@ShipraVarshney: असल में यह "मुक्केबाजी या varargs का उपयोग किए बिना एक मैच खोजने का प्रयास करें। फिर मुक्केबाजी का उपयोग करके एक मैच खोजने का प्रयास करें, लेकिन varargs नहीं। फिर मुक्केबाजी और varargs का उपयोग कर एक मैच खोजने की कोशिश करें।" –

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