मुझे डर लगता है। मुझे नहीं पता कि उनके लिए क्या उपयोग करना है।
साथ ही, लोगों को जितने चाहें उतने तर्क वितर्क करने देना खतरनाक लगता है।
एक संदर्भ का उदाहरण क्या है जो उनका उपयोग करने के लिए एक अच्छी जगह होगी?
मुझे डर लगता है। मुझे नहीं पता कि उनके लिए क्या उपयोग करना है।
साथ ही, लोगों को जितने चाहें उतने तर्क वितर्क करने देना खतरनाक लगता है।
एक संदर्भ का उदाहरण क्या है जो उनका उपयोग करने के लिए एक अच्छी जगह होगी?
जवाबों:
Varargs किसी भी विधि के लिए उपयोगी होते हैं जिन्हें वस्तुओं की अनिश्चित संख्या से निपटने की आवश्यकता होती है । एक अच्छा उदाहरण है String.format
। प्रारूप स्ट्रिंग किसी भी संख्या में मापदंडों को स्वीकार कर सकती है, इसलिए आपको किसी भी संख्या में ऑब्जेक्ट को पास करने के लिए एक तंत्र की आवश्यकता होती है।
String.format("This is an integer: %d", myInt);
String.format("This is an integer: %d and a string: %s", myInt, myString);
अंगूठे का एक अच्छा नियम होगा:
"किसी भी विधि (या निर्माणकर्ता) के लिए varargs का उपयोग करें जिसे इनपुट के रूप में T (जो भी प्रकार T हो सकता है) की एक सरणी की आवश्यकता है"।
इससे इन तरीकों से कॉल करना आसान हो जाएगा (कोई ज़रूरत नहीं है) new T[]{...}
)।
आप एक List<T>
तर्क के साथ विधियों को शामिल करने के लिए इस नियम का विस्तार कर सकते हैं , बशर्ते कि यह तर्क केवल इनपुट के लिए है (यानी, सूची विधि द्वारा संशोधित नहीं है)।
इसके अतिरिक्त, मैं उपयोग करने से बचना चाहूँगा f(Object... args)
क्योंकि इसकी अस्पष्ट अस्पष्ट एपीआई के साथ प्रोग्रामिंग की ओर फिसल जाता है।
उदाहरणों के संदर्भ में, मैंने इसका उपयोग DesignGridLayout में किया है , जहां मैं JComponent
एक कॉल में कई s जोड़ सकता हूं :
layout.row().grid(new JLabel("Label")).add(field1, field2, field3);
ऐड () विधि के ऊपर कोड के रूप में परिभाषित किया गया है add(JComponent... components)
।
अंत में, इस तरह के तरीकों के कार्यान्वयन को इस तथ्य का ध्यान रखना चाहिए कि इसे एक खाली वैरग के साथ कहा जा सकता है! यदि आप कम से कम एक तर्क थोपना चाहते हैं, तो आपको एक बदसूरत चाल का उपयोग करना होगा:
void f(T arg1, T... args) {...}
मैं इस चाल को बदसूरत मानता हूं क्योंकि विधि का क्रियान्वयन सिर्फ T... args
इसके तर्कों की सूची में होने से कम सीधा होगा ।
उम्मीद है कि इस तरह के रूपांतरों के बारे में बात को स्पष्ट करने में मदद मिलेगी।
if (args.length == 0) throw new RuntimeException("foo");
इसके बजाय एक पूर्व शर्त जाँच जोड़ने पर विचार किया? (चूंकि कॉलर अनुबंध का उल्लंघन कर रहा था)
void f(T arg1, T... args)
हमेशा इसके लिए सुझाव यह सुनिश्चित करता है कि इसे बिना तर्क के कभी नहीं बुलाया जाए, बिना रनटाइम तक इंतजार किए बिना।
मैं डिबगिंग के प्रयोजनों के लिए लॉग के आउटपुट के लिए अक्सर वैरग का उपयोग करता हूं।
मेरे ऐप में बहुत अधिक हर वर्ग में एक विधि डिबगप्रिंट () है:
private void debugPrint(Object... msg) {
for (Object item : msg) System.out.print(item);
System.out.println();
}
फिर, कक्षा के तरीकों के भीतर, मेरे पास निम्नलिखित की तरह कॉल हैं:
debugPrint("for assignment ", hwId, ", student ", studentId, ", question ",
serialNo, ", the grade is ", grade);
जब मैं संतुष्ट हो जाता हूं कि मेरा कोड काम कर रहा है, तो मैं डिबगप्रिंट () विधि में कोड को टिप्पणी करता हूं ताकि लॉग में बहुत अधिक बाहरी और अवांछित जानकारी न हो, लेकिन मैं व्यक्तिगत कॉल को डिबगप्रिंट () के लिए छोड़ सकता हूं। बाद में, यदि मुझे कोई बग मिल जाता है, तो मैं बस डिबगप्रिंट () कोड को अनसुना कर देता हूं, और डिबगप्रिंट () पर मेरे सभी कॉल पुन: सक्रिय हो जाते हैं।
बेशक, मैं बस के रूप में आसानी से चर सकते हैं और इसके बजाय निम्नलिखित कर सकते हैं:
private void debugPrint(String msg) {
System.out.println(msg);
}
debugPrint("for assignment " + hwId + ", student " + studentId + ", question "
+ serialNo + ", the grade is " + grade);
हालाँकि, इस मामले में, जब मैं डीबगप्रिंट () कोड के बारे में टिप्पणी करता हूं, तो सर्वर को अभी भी हर कॉल में सभी वेरिएबल्स को डीबगप्रिंट () तक पहुंचाने की परेशानी से गुजरना पड़ता है, भले ही परिणामी स्ट्रिंग के साथ कुछ भी नहीं किया गया हो। यदि मैं varargs का उपयोग करता हूं, हालांकि, सर्वर को केवल एक सरणी में रखना होगा इससे पहले कि यह पता चले कि उसे उनकी आवश्यकता नहीं है। बहुत समय बच जाता है।
जब हम एक विधि में पारित होने वाले तर्कों की संख्या के बारे में अनिश्चित होते हैं, तो वैराग का उपयोग किया जा सकता है। यह पृष्ठभूमि में अनिर्दिष्ट लंबाई के मापदंडों का एक सरणी बनाता है और ऐसे पैरामीटर को रनटाइम में एक सरणी के रूप में माना जा सकता है।
यदि हमारे पास एक ऐसी विधि है जिसे विभिन्न प्रकार के मापदंडों को स्वीकार करने के लिए अधिभारित किया जाता है, तो विधि को अलग-अलग समय में अधिभारित करने के बजाय, हम बस वार्गस अवधारणा का उपयोग कर सकते हैं।
इसके अलावा जब पैरामीटर का प्रकार भिन्न होता है तो "ऑब्जेक्ट ... टेस्ट" का उपयोग करके कोड को बहुत सरल किया जाएगा।
उदाहरण के लिए:
public int calculate(int...list) {
int sum = 0;
for (int item : list) {
sum += item;
}
return sum;
}
यहाँ परोक्ष रूप से int प्रकार (सूची) की एक सरणी को पैरामीटर के रूप में पारित किया जाता है और कोड में एक सरणी के रूप में माना जाता है।
इस लिंक को बेहतर तरीके से समझने के लिए (इस अवधारणा को स्पष्ट रूप से समझने में इससे मुझे बहुत मदद मिली): http://www.javadb.com/use-varargs-in-java
पुनश्च: यहां तक कि मैं varargs का उपयोग करने से डरता था जब मैंने इसे बंद नहीं किया था। लेकिन अब मुझे इसकी आदत है। जैसा कि कहा जाता है: "हम ज्ञात से चिपके रहते हैं, अज्ञात से डरते हैं", इसलिए बस इसे जितना हो सके उतना उपयोग करें और आप भी इसे पसंद करना शुरू कर देंगे :)
वर्गास जावा संस्करण 1.5 में जोड़ा गया फीचर है।
इसका उपयोग क्यों करें?
यह कैसे काम करता है?
यह दिए गए तर्कों के साथ एक सरणी बनाता है और विधि के लिए सरणी को पास करता है।
उदाहरण :
public class Solution {
public static void main(String[] args) {
add(5,7);
add(5,7,9);
}
public static void add(int... s){
System.out.println(s.length);
int sum=0;
for(int num:s)
sum=sum+num;
System.out.println("sum is "+sum );
}
}
आउटपुट:
2
योग 12 है
3
राशि 21 है
मेरे पास एक वैराग से संबंधित भय भी है:
यदि कॉलर विधि के लिए एक स्पष्ट सरणी में गुजरता है (कई मापदंडों के विपरीत), तो आप उस सरणी के लिए एक साझा संदर्भ प्राप्त करेंगे।
यदि आपको इस सरणी को आंतरिक रूप से संग्रहीत करने की आवश्यकता है, तो आप कॉलर को बाद में बदलने में सक्षम होने से बचने के लिए पहले इसे क्लोन करना चाह सकते हैं।
Object[] args = new Object[] { 1, 2, 3} ;
varArgMethod(args); // not varArgMethod(1,2,3);
args[2] = "something else"; // this could have unexpected side-effects
हालांकि यह वास्तव में किसी भी प्रकार की वस्तु में गुजरने से अलग नहीं है, जिसकी स्थिति बाद में बदल सकती है, क्योंकि सरणी आमतौर पर (सरणी के बजाय कई तर्कों के साथ कॉल के मामले में) संकलक द्वारा बनाई गई एक ताजा एक आंतरिक रूप से जिसे आप सुरक्षित रूप से बना सकते हैं उपयोग, यह निश्चित रूप से अप्रत्याशित व्यवहार है।
मैं अक्सर ऐसे निर्माणकर्ताओं के लिए varargs का उपयोग करता हूं जो किसी प्रकार की फ़िल्टर ऑब्जेक्ट ले सकते हैं। उदाहरण के लिए, Hadoop पर आधारित हमारे सिस्टम का एक बड़ा हिस्सा एक Mapper पर आधारित है जो JSON के लिए क्रमांकन और आइटम के डीरिएलाइज़ेशन को संभालता है, और कई प्रोसेसर को लागू करता है जो प्रत्येक सामग्री का एक आइटम लेते हैं और इसे संशोधित करते हैं और इसे वापस करते हैं, या अशक्त करते हैं। अस्वीकार करना।
Var-Args के जावा डॉक में, यह var args का उपयोग काफी स्पष्ट है:
http://docs.oracle.com/javase/1.5.0/docs/guide/language/varargs.html
उपयोग के बारे में यह कहता है:
"तो आपको वेरिएग का उपयोग कब करना चाहिए? एक ग्राहक के रूप में, जब भी एपीआई उन्हें ऑफर करता है, तो आपको उनका लाभ उठाना चाहिए। कोर एपीआई में महत्वपूर्ण उपयोगों में प्रतिबिंब, संदेश स्वरूपण और नई प्रिंट सुविधा शामिल है। एपीआई डिजाइनर के रूप में, आपको उनका उपयोग करना चाहिए। विरल रूप से, केवल जब लाभ वास्तव में सम्मोहक होता है। आम तौर पर बोलना, आपको एक varargs पद्धति को अधिभार नहीं देना चाहिए, या प्रोग्रामर के लिए यह पता लगाना मुश्किल होगा कि कौन सा ओवरलोडिंग कहा जाता है। "