2012-01-12 16 views
13

मैं सोच रहा था कि जावा में Foo(Object[] args) को Foo(Object... args) के साथ ओवरलोड करने की अनुमति क्यों नहीं है, हालांकि उनका उपयोग अलग-अलग तरीके से किया जाता है? जबकि अन्य रूपजावा में फू (ऑब्जेक्ट ...) के साथ फू (ऑब्जेक्ट ...) को अधिभारित करने की अनुमति क्यों नहीं है?

Foo(new Object[]{new Object(), new Object()}); 

:

Foo(Object... args){} 

की तरह इस्तेमाल किया जाता है:

Foo(Object[] args){} 

की तरह प्रयोग किया जाता है

Foo(new Object(), new Object()); 

वहाँ इसके पीछे किसी भी कारण है?

+0

दिलचस्प प्रश्न +1 – mKorbel

+1

मुझे कुछ याद आ रहा है, लेकिन आपको ओवरलोड की आवश्यकता क्यों है? यदि आप अपनी विधि को 'शून्य फू (ऑब्जेक्ट ... तर्क) के रूप में घोषित करते हैं तो आप इसे ** ** ** foo (नया ऑब्जेक्ट(), नया ऑब्जेक्ट()) ** ** या ** 'foo (नया ऑब्जेक्ट [] {नया ऑब्जेक्ट(), नया ऑब्जेक्ट()}) 'और एक ही परिणाम प्राप्त करें। एक उदाहरण के लिए [यह संबंधित प्रश्न] देखें (http://stackoverflow.com/questions/1656901/varargs-and-the-argument)। –

+0

vararg टाइप किया गया विधि हस्ताक्षर के लिए सिर्फ एक झंडा है जो अंतिम घोषित सरणी (जैसे 'int [] 'या' ऑब्जेक्ट []') को vararg प्रकार में ट्रांसमिट कर रहा है। इसके अलावा - विधि हस्ताक्षर के बीच कोई अंतर नहीं। वही सवाल होगा जैसे 'निजी' और 'सार्वजनिक' विधि अधिभारित नहीं किया जा सकता है। – bestsss

उत्तर

25

यह 15.12.2.5 Choosing the Most Specific Method इस बारे में बात करते हैं, लेकिन यह काफी जटिल है। जैसे Foo (संख्या ... ints) और Foo (Integer ... ints) के बीच चयन

पिछड़े संगतता के हित में, ये प्रभावी रूप से एक ही चीज़ हैं।

public Foo(Object... args){} // syntactic sugar for Foo(Object[] args){} 

// calls the varargs method. 
Foo(new Object[]{new Object(), new Object()}); 

उदा। आप उन्हें अलग करने के लिए मुख्य()

रूप
public static void main(String... args) { 

एक तरह से परिभाषित कर सकते हैं वे वास्तव में ही नहीं हैं varargs

public Foo(Object o, Object... os){} 

public Foo(Object[] os) {} 

Foo(new Object(), new Object()); // calls the first. 

Foo(new Object[]{new Object(), new Object()}); // calls the second. 

से पहले एक तर्क लेने के लिए है। सूक्ष्म अंतर यह है कि जब आप एक सरणी को एक सरणी पास कर सकते हैं, तो आप एक सरणी पैरामीटर को varargs के रूप में नहीं मान सकते हैं।

public Foo(Object... os){} 

public Bar(Object[] os) {} 

Foo(new Object[]{new Object(), new Object()}); // compiles fine. 

Bar(new Object(), new Object()); // Fails to compile. 

इसके अतिरिक्त, एक varags अंतिम पैरामीटर होना चाहिए।

public Foo(Object... os, int i){} // fails to compile. 

public Bar(Object[] os, int i) {} // compiles ok. 
+0

+1 अच्छा स्पष्टीकरण। क्या इसके लिए कोई भाषा विनिर्देश लिखा गया है? –

+0

:-) अच्छा उत्तर +1 – mKorbel

+0

कृपया [इस सवाल] पर एक नज़र डालें (http://stackoverflow.com/q/14937948/597657) कृपया। –

3

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

Object[] a = new Object[10]; 
Foo(a); // array or vararg? 

और जावा की आवश्यकता है वहाँ हमेशा हर विधि मंगलाचरण के लिए एक सबसे विशिष्ट तरीका हो कि: यदि आप एक ही कक्षा में दोनों घोषित है, वहाँ जो विधि आप चाहते थे यह पता लगाने का कोई तरीका नहीं है जब thusly बुला होगा। के लिए क्यों, पीटर का जवाब देखें।

+0

वे * बिल्कुल * वही हैं, अस्पष्टता नहीं, वे एक ही कक्षा में मौजूद नहीं हो सकते – bestsss

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