2016-05-19 48 views
11

निम्न उदाहरण कोड पर विचार करें:जावा अधिक भार: संदर्भ कॉल करने के लिए अस्पष्ट

public class TestClass { 

    public void doSth(String str, String l, Object... objects) { 
     System.out.println("A"); 
    } 

    public void doSth(String str, Object... objects) { 
     System.out.println("B"); 
    } 

} 

जब मैं अब new TestClass().doSth("foo", "bar") फोन मैं अपेक्षित परिणाम A मिलता है। लेकिन अगर मैं एक आदिम प्रकार के पैरामीटर l chaging द्वारा पहली विधि की विधि हस्ताक्षर बदलने के लिए:

public class TestClass { 

    public void doSth(String str, long l, Object... objects) { 
     System.out.println("A"); 
    } 

    public void doSth(String str, Object... objects) { 
     System.out.println("B"); 
    } 

} 

new TestClass().doSth("foo", 2L) बुला एक reference to call ambiguous संकलन समय त्रुटि निकलेगा।

मैंने उस समय के बारे में कुछ समय के बारे में सोचा और this stackoverflow question से परामर्श लिया, लेकिन मुझे यह समझने में असमर्थ था कि ऐसा क्यों होता है। मेरी राय में doSth("foo", 2L)doSth(String string, long l, Object... obj) हस्ताक्षर के लिए अधिक विशिष्ट है और संकलक को इस निष्कर्ष पर भी आने की अनुमति देनी चाहिए।

+0

जाहिर है प्राइमेटिव ऑब्जेक्ट्स भी हो सकते हैं? –

+0

@blahfunk, हाँ, उन्हें – Andrew

+0

लपेटा जा सकता है केवल एकमात्र स्पष्टीकरण जो दिमाग में आता है [Autoboxing] (https://docs.oracle.com/javase/tutorial/java/data/autoboxing.html) है, लेकिन यह होना चाहिए एक रूपांतरण-चरण "आगे" विधि के आदिम संस्करण से दूर है। – Turing85

उत्तर

5

इस मामले में, ऑटो-मुक्केबाजी आपको दुःख का कारण बन रही है। विडंबना यह है कि इससे पहले कि आप सही हैं - "लंबा" संस्करण आसानी से उठाया जाएगा।

मूल रूप से संकलक जानता है कि यह आपके मूल्य से एक लंबा बना सकता है, बेशक, एक वस्तु है। तो यह अभी भी उलझन में है क्योंकि या तो लंबे या लंबे संस्करण का उपयोग किया जा सकता है। क्या यह दूसरे से बढ़िया है? शायद लेकिन यह एक बहुत अच्छी लाइन है।

+1

के बीच अंतर करने की कोशिश कर रहा है ठीक है, [चरण 1] (http://docs.oracle.com/javase/specs/jls/se7/html/jls-15। एचटीएमएल # जेएलएस -15.12.2) जेएलएस में स्पष्ट रूप से निर्दिष्ट करता है * मुक्केबाजी या अनबॉक्सिंग रूपांतरण की अनुमति के बिना ओवरलोड रिज़ॉल्यूशन निष्पादित करता है *। इस चरण में, ऑटोबॉक्सिंग नहीं किया जाता है। ऐसा लगता है कि 'doSth (स्ट्रिंग स्ट्र, लांग एल, ऑब्जेक्ट ... ऑब्जेक्ट्स)' उस चरण में चुना जाना चाहिए। क्या मैं कुछ भूल रहा हूँ? – Tunaki

+0

यह मजाकिया है। यह केवल तबाही क्यों नहीं होता है, जब केवल एक पैरामीटर होता है, यानी 'doSth (long l) 'और' doSth (ऑब्जेक्ट ओ) '? – Turing85

+3

@ टुनकी चरण 1 और 2 में परिवर्तनीय धर्मार्थ विधियों को भी शामिल किया गया है, इसलिए ओपी के तरीकों को चरण 3 तक नहीं माना जाता है। उत्सुकता से, 'doSth ("foo", 2L, null)' पहली बुलेट के तहत इटालिसिक नोट के कारण संकलित होगा (आपके लिंक में) कहते हैं। – Radiodef

1

इस स्थिति में, मैं केवल अपने अवलोकन की रिपोर्ट कर सकता हूं, सटीक तर्क नहीं कि जावा क्यों व्यवहार करता है, जैसा कि करता है।

पहले,

void doSth(long l) {...} 
void doSth(Object o) {...} 

करने के तरीकों को बदलने समस्या से छुटकारा हो जाता है, यानी doSth(2L); अपेक्षित परिणाम निकलेगा।

, एक कदम आगे जा रहे हैं विधि पैरामीटर को बदलने

void doSth(long... ls) {...} 
void doSth(Object... os) {...} 

एक साथ varargs करने के लिए कॉल doSth(2l); के साथ एक ही संकलन त्रुटि के रूप में ओ पी द्वारा रिपोर्ट अर्जित करता है।

इस चरण में मेरा सुझाव यह है कि पैरामीटर को एक सरणी में encapusalting, Autoboxing के साथ एक साथ विनाश का कारण बनता है। जेएलएस के बारे में मेरा ज्ञान इस उचित तरीके से व्याख्या करने के लिए पर्याप्त नहीं है।

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