2012-10-23 12 views
92

मैं एक प्रश्नोत्तरी में यह सवाल भर में आया था,एक ओवरलोडेड विधि कैसे चुना जाता है जब पैरामीटर शाब्दिक शून्य मान होता है?

public class MoneyCalc { 

    public void method(Object o) { 
     System.out.println("Object Verion"); 
    } 

    public void method(String s) { 
     System.out.println("String Version"); 
    } 

    public static void main(String args[]) { 
     MoneyCalc question = new MoneyCalc(); 
     question.method(null); 
    } 
} 

इस कार्यक्रम का उत्पादन "स्ट्रिंग संस्करण" है। लेकिन मुझे समझ में नहीं आया कि एक ओवरलोडेड विधि को शून्य करने के कारण स्ट्रिंग संस्करण का चयन क्यों किया गया। क्या शून्य स्ट्रिंग वेरिएबल कुछ भी नहीं है?

लेकिन जब कोड को बदल दिया गया है,

public class MoneyCalc { 

    public void method(StringBuffer sb) { 
     System.out.println("StringBuffer Verion"); 
    } 

    public void method(String s) { 
     System.out.println("String Version"); 
    } 

    public static void main(String args[]) { 
     MoneyCalc question = new MoneyCalc(); 
     question.method(null); 
    } 
} 

यह कह

+0

आप एक शून्य मान के लिए एक स्ट्रिंग असाइन कर सकते हैं तो यह वैध है और जावा और सबसे प्रोग्रामिंग भाषाओं के लिए आदेश निकटतम प्रकार के लिए फिट है और उसके बाद आपत्ति उठाने का। – JonH

+0

http://stackoverflow.com/a/1572499/231290 – Lukasz

+5

जाहिर है इस लोग हैं, जो केवल शीर्षक पढ़ द्वारा डुप्लीकेट के रूप में बंद हो गया। यहां वास्तविक सवाल यह है कि एक विशिष्ट अधिभार क्यों चुना गया था, न कि "शून्य क्या है"। – interjay

उत्तर

96

"विधि विधि (StringBuffer) प्रकार MoneyCalc के लिए अस्पष्ट है" एक संकलन त्रुटि देता है अशक्त एक स्ट्रिंग वैरिएबल है कुछ भी इंगित नहीं कर रहा है?

एक शून्य संदर्भ किसी भी वर्ग प्रकार की अभिव्यक्ति में परिवर्तित किया जा सकता है। तो String के मामले में, यह ठीक है क्योंकि जावा कम्पाइलर सबसे विशिष्ट अधिभार उठाता है, प्रति section 15.12.2.5 of the JLS रूप

String x = null; 

यहाँ String अधिभार चुना जाता है। विशेष रूप से:

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

अपने दूसरे मामले में, दोनों तरीकों अभी भी लागू होते हैं, लेकिन न तो String है और न ही StringBuffer इसलिए न तो विधि अन्य, इसलिए संकलक त्रुटि की तुलना में अधिक विशिष्ट है, अन्य की तुलना में अधिक विशिष्ट है।

+3

और स्ट्रिंग अधिभार ऑब्जेक्ट अधिभार से अधिक विशिष्ट कैसे है? – user1610015

+9

क्योंकि 'ऑब्जेक्ट' किसी भी प्रकार का ले सकता है और उसे 'ऑब्जेक्ट' में लपेट सकता है, जबकि 'स्ट्रिंग' केवल 'स्ट्रिंग' ले सकता है। इस मामले में, 'ऑब्जेक्ट' प्रकार की तुलना में 'स्ट्रिंग' एक प्रकार का अधिक विशिष्ट है। – JonH

+0

@ user1610015: विवरण के लिए जेएलएस देखें - मैंने जवाब में "अनौपचारिक" संस्करण शामिल किया है। –

2

आप एक string करने के लिए एक null मूल्य प्रदान कर सकते हैं तो यह वैध है और जावा और सबसे प्रोग्रामिंग भाषाओं के लिए आदेश निकटतम प्रकार के लिए फिट है और उसके बाद आपत्ति उठाने का।

2

शीर्षक में सवाल का जवाब करने के लिए: null न तो एक String है और न ही एक Object है, लेकिन या तो के लिए एक संदर्भ null को सौंपा जा सकता।

मैं वास्तव में इस कोड को भी संकलित हैरान कर रहा हूँ। मैंने पहले कुछ ऐसा करने की कोशिश की और मुझे एक कंपाइलर त्रुटि मिली जिसमें कहा गया कि कॉल संदिग्ध था।

हालांकि, इस मामले में, ऐसा लगता है संकलक की तरह विधि जो खाद्य श्रृंखला पर सबसे कम है चुनने है। यह मानते हुए कि आप मदद करने के लिए विधि का कम से कम सामान्य संस्करण चाहते हैं।

मैं अगर मैं ऊपर उदाहरण है जहाँ मैं इस (प्रतीत होता है) ठीक उसी परिदृश्य में एक संकलक त्रुटि मिली है, हालांकि खुदाई कर सकते हैं देखने के लिए ...]

संपादित होगा: अच्छा। संस्करण मैंने बनाया में, मैं स्वीकार करने के लिए एक String और एक Integer दो अतिभारित विधियाँ था। इस परिदृश्य में, वहाँ (Object और String के रूप में) नहीं "सबसे विशिष्ट" पैरामीटर है, इसलिए यह अपने कोड में विपरीत उन दोनों के बीच नहीं चुन सकते हैं,।

बहुत शांत सवाल!

+0

शून्य न तो है, लेकिन इसे दोनों को सौंपा जा सकता है, यह अंतर है और यह संकलित करेगा क्यों नहीं होगा - यह बिल्कुल मान्य कोड है। – JonH

-1

मैं कहूंगा कि न। नल एक राज्य नहीं है। इस पर अधिक जानकारी के लिए यह link देखें (लेख SQL पर लागू होता है, लेकिन मुझे लगता है कि यह आपके प्रश्न के साथ भी मदद करता है)।

+0

'शून्य' बहुत निश्चित रूप से एक मूल्य है, जैसा कि जेएलएस में परिभाषित किया गया है। –

9

साथ ही, JLS 3.10.7 भी घोषणा करता है कि "शून्य" "अशक्त प्रकार" की एक शाब्दिक मूल्य है। इसलिए वहां "नल" नामक एक प्रकार मौजूद है।

बाद में, JLS 4.1 बताता है कि एक शून्य प्रकार मौजूद है जिसमें चर घोषित करना असंभव है, लेकिन आप इसे केवल शून्य शब्दशः के माध्यम से उपयोग कर सकते हैं। बाद में यह कहता है:

शून्य संदर्भ हमेशा किसी संदर्भ प्रकार में विस्तृत संदर्भ रूपांतरण से गुज़र सकता है।

क्यों संकलक स्ट्रिंग के लिए इसे चौड़ा करने के लिए चुनता अच्छी तरह से Jon's answer में विस्तार से बताया जा सकता है।

+0

मुझे पूरा यकीन है कि प्रकार शून्य है। – xavierm02

+2

@ xavierm02 जावा भाषा विशिष्टता में इसका कोई उल्लेख नहीं है। क्या आप अपना संदर्भ उद्धृत कर सकते हैं ताकि हम सभी आपके दावे की पुष्टि कर सकें? –

+0

मैंने कभी यह बात नहीं पढ़ी। लेकिन मैंने इस गर्मी में कुछ जावा किया था और आप ऑब्जेक्ट लेने वाली विधि को शून्य ऑब्जेक्ट लेने के तरीके से अधिभारित कर सकते हैं। – xavierm02

0

के रूप में स्ट्रिंग प्रकार ऑब्जेक्ट प्रकार की तुलना में अधिक विशिष्ट है। आइए मान लें कि आप एक और विधि जोड़ते हैं जो एक इंटीजर प्रकार लेता है।

public void method(Integer i) { 
     System.out.println("Integer Version"); 
    } 

फिर आपको एक कंपाइलर त्रुटि मिल जाएगी जिसमें कहा गया है कि कॉल संदिग्ध है। अब हम एक ही प्राथमिकता के साथ दो समान रूप से विशिष्ट तरीकों के रूप में।

0

जावा कम्पाइलर अशक्त आवंटित करने के लिए सबसे व्युत्पन्न वर्ग प्रकार देता है।

class A{ 

    public void methodA(){ 
     System.out.println("Hello methodA"); 
    } 
} 

class B extends A{ 
    public void methodB(){ 
     System.out.println("Hello methodB"); 
    } 
} 

class C{ 
    public void methodC(){ 
     System.out.println("Hello methodC"); 
    } 
} 

public class MyTest { 

    public static void fun(B Obj){ 
     System.out.println("B Class."); 
    } 
    public static void fun(A Obj){ 
     System.out.println("A Class."); 
    } 

    public static void main(String[] args) { 
     fun(null); 
    } 
} 

उत्पादन: बी क्लास

यहाँ यह समझने के लिए उदाहरण है।

दूसरी ओर

:

public class MyTest { 

    public static void fun(C Obj){ 
     System.out.println("B Class."); 
    } 
    public static void fun(A Obj){ 
     System.out.println("A Class."); 
    } 

    public static void main(String[] args) { 
     fun(null); 
    } 
} 

परिणाम: विधि मज़ा (सी) प्रकार के लिए अस्पष्ट है MyTest

आशा है कि यह इस मामले में बेहतर समझने में मदद मिलेगी।

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

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