2008-10-06 9 views
5

पर विचार के लिए निम्न विधि हस्ताक्षर:वस्तु सरणियों

public fooMethod (Foo[] foos) { /*...*/ } 

और

public fooMethod (Foo... foos) { /*...*/ } 

स्पष्टीकरण: पूर्व एक तर्क के रूप फू-वस्तुओं की एक सरणी लेता है - fooMethod(new Foo[]{..}) - जबकि बाद प्रकार फू के तर्कों की मनमानी मात्रा लेता है, और उन्हें विधि के भीतर Foo: s के सरणी के रूप में प्रस्तुत करता है - fooMethod(fooObject1, fooObject2, etc...)।

जावा दोनों फिट होने पर फिट फेंकता है, दावा करते हुए कि वे डुप्लिकेट विधियां हैं। मैंने कुछ जासूसी कार्य किया, और पाया कि पहली घोषणा वास्तव में फू ऑब्जेक्ट्स की एक स्पष्ट सरणी की आवश्यकता है, और यह विधि कॉल करने का यही एकमात्र तरीका है। दूसरा तरीका वास्तव में फू तर्कों की मनमानी मात्रा दोनों को स्वीकार करता है और फू ऑब्जेक्ट्स की एक सरणी भी स्वीकार करता है।

तो सवाल यह है कि चूंकि बाद की विधि अधिक लचीली प्रतीत होती है, क्या पहले उदाहरण का उपयोग करने के कोई कारण हैं, या क्या मुझे कुछ भी महत्वपूर्ण याद आया है?

+0

जावा को नहीं जानते, यह अंधेरे में एक स्टैब है, लेकिन मुझे लगता है कि पहला मामूली रूप से अधिक कुशल है, क्योंकि: ए) आप केवल एक पॉइंटर को पास कर रहे होंगे, और बी) आप होंगे स्मृति के एक संगत हिस्से में एक सूचक को गुजरना। –

+0

@monoxide: नहीं, दोनों रूपों समकक्ष कॉलिंग बाइटकोड उत्पन्न करते हैं, दोनों रूपों को पास करने के लिए एक सरणी बनाने की आवश्यकता होती है। –

+0

दूसरा रूप पहले के लिए सिंटैक्टिक चीनी है। तो, fooMethod (नया फू (1), नया फू (2)) fooMethod (नया फू [] {नया फू (1), नया फू (2)}) –

उत्तर

12

ये विधियां वास्तव में वही हैं।

इस सुविधा को varargs कहा जाता है और यह एक कंपाइलर सुविधा है। दृश्यों के पीछे पूर्व संस्करण में अनुवाद है।

यदि आप ऑब्जेक्ट स्वीकार करते हैं तो एक गड़बड़ी है ... और आपने ऑब्जेक्ट [] के प्रकार का एक पैरामीटर भेजा है!

+0

जावा आपको इसके बारे में चेतावनी देता है, और आपको या तो (ऑब्जेक्ट) सरणी (वैरिएडिक मोड के लिए) या (ऑब्जेक्ट []) सरणी (गैर-चरणीय मोड के लिए) लिखने के लिए कहता है। :-) –

1

उत्तरार्द्ध जावा 5 में पेश किया गया था और मौजूदा पुस्तकालयों को धीरे-धीरे इसका समर्थन करने के लिए पुन: कार्य किया जा रहा है। आप अभी भी तनाव के लिए पूर्व का उपयोग कर सकते हैं कि विधि को 2+ इनपुट की आवश्यकता है, साथ ही इस पर प्रतिबंध भी हैं कि ... का उपयोग किया जा सकता है।

+0

के समान है, इसके अलावा यह इस तरह के कुछ भी नहीं दबाता है, और वास्तव में 0 या 1 इनपुट की अनुमति देता है (जब तक अन्यथा दस्तावेज़ीकरण में निर्दिष्ट नहीं किया जाता है, इस मामले में वैरिएडिक फॉर्म उतना ही अच्छा होता है)। –

0

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

क्या आप उम्मीद करते हैं कि आपकी विधि के कॉलर को फू के हाथ में तैयार करने की आवश्यकता है? फिर Foo [] संस्करण का उपयोग करें। एक सरणी के बजाय फू के "गुच्छा" होने की संभावना पर बल देने के लिए varargs संस्करण का उपयोग करें।

varargs के लिए एक शास्त्रीय उदाहरण पहली (सी # में, पता नहीं कैसे जावा में इसकी कहा जाता है) स्ट्रिंग प्रारूप:

string Format(string formatString, object... args) 

यहाँ आप आर्ग विभिन्न प्रकार के होने की उम्मीद है, तो तर्क की एक सरणी होने काफी अनौपचारिक होगा, इसलिए varargs संस्करण।

कुछ में दूसरी ओर

तरह
string Join(string[] substrings, char concatenationCharacter) 

किसी सरणी का उपयोग कर पूरी तरह से उचित है।

यह भी ध्यान रखें कि आप पैरामीटर-सूची के अंत में एकाधिक सरणी पैरामीटर और केवल एक vararg पैरामीटर हो सकते हैं।

3

मैं Shimi के विवरण में जोड़ने के लिए जोड़ने के लिए varargs वाक्य रचना का एक और प्रतिबंध है कि vararg पिछले घोषित पैरामीटर होना चाहिए है कि चाहते हैं। तो आप यह नहीं कर सकते:

void myMethod(String... values, int num); 

इसका मतलब है कि किसी दिए गए विधि में केवल एक ही vararg पैरामीटर हो सकता है।ऐसे मामलों में जहां आप एकाधिक सरणी पास करना चाहते हैं, आप उनमें से केवल एक के लिए varargs का उपयोग कर सकते हैं।

प्रैक्टिस में, जब आप तर्कों को एक सरणी के बजाय अलग-अलग मानों की मनमानी संख्या के रूप में मानते हैं तो वेरगास सबसे अच्छे होते हैं। Java5 उन्हें एक सरणी में बस नक्शा बनाता है क्योंकि यह करने के लिए सबसे सुविधाजनक बात थी।

एक अच्छा उदाहरण है स्ट्रिंग.फॉर्मैट()। यहां, varargs पहले तर्क में प्रारूप प्लेसहोल्डर के खिलाफ मेल खाते हैं।