2011-04-03 9 views
16

मेरे पास निम्न कोड है:जावा में मिटाएं और ओवरलोडिंग टाइप करें: यह क्यों काम करता है?

public class Pair< T, U > { 
    public T first; 
    public U second; 
} 
public class Test { 
    public int method(Pair< Integer, Integer > pair) { 
     return 0; 
    } 
    public double method(Pair< Double, Double > pair) { 
     return 1.0; 
    } 
} 

यह वास्तव में संकलित करता है और काम करता है जैसे किसी की उम्मीद होगी। लेकिन अगर रिटर्न प्रकार समान होते हैं, तो यह संकलित नहीं होता है, अपेक्षित "नाम टकराव: विधि (जोड़ी) और विधि (जोड़ी) में एक ही मिट है"

यह देखते हुए कि रिटर्न टाइप isn ' विधि हस्ताक्षर का हिस्सा नहीं है, यह अधिभार संभव कैसे है?

+1

[जेवाक के साथ जावा जेनेरिक कोड संकलन, संभव ग्रहण हेलीओस के साथ विफल रहता है] के संभावित डुप्लिकेट (http://stackoverflow.com/questions/3452859/java-generics-code-compiles-with-javac-fails-with-eclipse- हेलीओस) – BalusC

उत्तर

9

पर विचार करें निम्नलिखित 4 तरीकों

  Java code      bytecode 

m1: Byte f(List<Byte> list)   f List -> Byte 
m2: Long f(List<Byte> list)   f List -> Long 
m3: Byte f(List<Long> list)   f List -> Byte 
m4: Long f(List<Long> list)   f List -> Long 

वर्तमान जावा भाषा युक्ति के अनुसार,

  • एम 1 और एम 2 साथ नहीं रह सकते, और न ही एम 3 और m4 कर सकते हैं। क्योंकि उनके पास समान पैरामीटर प्रकार हैं।

  • एम 1 और एम 3 सह-अस्तित्व में हो सकते हैं, तो एम 1 और एम 4 कर सकते हैं। क्योंकि उनके पास विभिन्न पैरामीटर प्रकार हैं।

लेकिन जावैक 6 केवल एम 1 + एम 4 की अनुमति देता है, एम 1 + एम 3 नहीं। यह विधियों के बाइटकोड प्रतिनिधित्व से संबंधित है, जिसमें रिटर्न प्रकार शामिल हैं। इसलिए, एम 1 + एम 4 ठीक है, लेकिन एम 1 + एम 3 नहीं है।

यह एक स्क्रूप है जहां जावा और जेवीएम चश्मा आंखों पर नजर नहीं देखते हैं। जावैक के लिए कोई "सही" तरीका नहीं है।

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

+1

स्पेक को क्या कहना चाहिए (जावा के बग डेटाबेस में कई प्रविष्टियों के अनुसार), इनमें से कोई भी विधि सह-अस्तित्व में नहीं हो सकती है, क्योंकि टाइप पैरामीटर ** के बाद समान पैरामीटर प्रकार ** हैं। –

+0

बाइटकोड प्रतिनिधित्व के लिए धन्यवाद; इससे समस्या बहुत स्पष्ट हो जाती है। इसलिए "विधि हस्ताक्षर" आमतौर पर केवल पैरामीटर को संदर्भित करता है, बाइटकोड में एक विधि हस्ताक्षर रिटर्न प्रकार शामिल है। –

+0

और [इस बग] के अनुसार (http://bugs.sun.com/view_bug.do?bug_id=6182950) यहां तक ​​कि m1 + m4 javac7 में अवैध होगा। यह दयालु है क्योंकि कभी-कभी 'कुछ टाइप एफ (कुछ क्लास )' के रूप में कुछ ओवरलोडेड विधियों के लिए बहुत उपयोगी है। ([इस सवाल] के जवाब में (http://stackoverflow.com/q/6641723/648313)) – Idolon

6

ओवरलोडिंग संकलन समय पर किया जाता है।

हालांकि जेनेरिक पैरामीटर रन-टाइम पर मिटा दिए जाते हैं, फिर भी वे ओवरलोड को हल करने के लिए कंपाइलर के लिए उपलब्ध हैं।

-1

मुझे विश्वास है कि आप वास्तव में गलत टाइपिंग देख रहे हैं। यह कहकर कि पहली विधि जोड़ी लेती है आप इसे एक बहुत ही विशिष्ट प्रकार दे रहे हैं। यह कहने की विधि है (स्ट्रिंग, स्ट्रिंग)। जोड़ी की दूसरी विधि विधि (व्यक्ति, व्यक्ति) कहने की तरह है। यह भी एक टाइपिंग स्तर पर बहुत विशिष्ट है। यदि आप विधि के लिए अपनी विधियों को बदल देंगे (जोड़ी <T,U>, जोड़ी <T,U>) और दो बार है, तो आप संकलन तोड़ देंगे।

तो संक्षिप्त उत्तर: चूंकि आपने दृढ़ता से दो अलग-अलग चीजों का अर्थ रखा है, जेनेरिक खेल नहीं रहे हैं, बस नियम टाइप कर रहे हैं।

1

एक जावा विधि हस्ताक्षर वास्तव में रिटर्न प्रकार शामिल करता है; यदि आपने कभी जेएनआई के साथ काम किया है तो आपने (एलपीएआर;) डी और (एलपीएआर;) I जैसे प्रकार के वर्णनकर्ताओं को टाइप किया है। वह अंतिम चरित्र आपके दो तरीकों के रिटर्न प्रकारों को दर्शाता है। यद्यपि जावा भाषा नियम यह है कि पैरामीटर दो अधिभारित विधियों के लिए भिन्न होना चाहिए, क्लास फ़ाइल प्रारूप वास्तव में केवल उनके रिटर्न प्रकारों के आधार पर विधियों को अलग कर सकता है। जब जेनेरिक प्रकार की जानकारी होती है तो संकलक को उनके तर्कों के आधार पर अधिभार को हल करने की अनुमति देने के लिए, तब तक जब तक रिटर्न प्रकार अलग होते हैं, तब तक त्रुटियों के अलग-अलग हस्ताक्षर होंगे, और यह सब ठीक काम करता है। यदि रिटर्न प्रकार समान हैं, हालांकि, विधियों के बाद विधियों के समान हस्ताक्षर होते हैं, तो कक्षा फ़ाइल अंतर नहीं बता सकती है, और आपको कोई समस्या है।

+0

यह सबसे अच्छा स्पष्टीकरण है जिसे मैं कहीं भी ढूंढ सकता हूं। धन्यवाद – kaustubh

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