जावा, मापदंडों में 3 डॉट्स


जवाबों:


986

इसका मतलब है कि शून्य या अधिक स्ट्रिंग ऑब्जेक्ट्स (या उनमें से एक सरणी) को उस पद्धति के लिए तर्क (ओं) के रूप में पारित किया जा सकता है।

यहां "तर्क की संख्या" खंड देखें: http://java.sun.com/docs/books/tutorial/java/javaOO/arguments.html#varargs

अपने उदाहरण में, आप इसे निम्नलिखित में से किसी के रूप में कह सकते हैं:

myMethod(); // Likely useless, but possible
myMethod("one", "two", "three");
myMethod("solo");
myMethod(new String[]{"a", "b", "c"});

महत्वपूर्ण नोट: इस तरह से पारित तर्क (एस) हमेशा एक सरणी है - भले ही बस एक ही हो। सुनिश्चित करें कि आप इसे विधि शरीर में इस तरह से व्यवहार करते हैं।

महत्वपूर्ण नोट 2: वह तर्क जो ...विधि हस्ताक्षर में अंतिम होना चाहिए। तो, myMethod(int i, String... strings)ठीक है, लेकिन myMethod(String... strings, int i)ठीक नहीं है।

अपनी टिप्पणी में स्पष्टीकरण के लिए वश का धन्यवाद।


112
आप गलत हैं, उस "एक या अधिक" में, varargs के साथ हम 0 या अधिक निर्दिष्ट कर सकते हैं, और यह हमेशा विधि में अंतिम पैरामीटर होना चाहिए। विधि x (स्ट्रिंग ... परम) को x () या विधि y (स्ट्रिंग प्राम, स्ट्रिंग ... परम) के रूप में कॉल किया जा सकता है, जिसे y ("1") के रूप में पुकारा जा सकता है
डेमियन लेसज़्स्की - वश

2
काश कि यह भी काम होता। myMethod ("एक", "दो", "तीन", नया स्ट्रिंग [] {"a", "b", "c" "});
2sb

2
आपको विधि 0 पैरामीटर देने की अनुमति क्यों है? यह सबसे अधिक संभावना ArrayIndexOutOfBoundsException को जन्म देगा। अब आपको हमेशा उस मामले को ध्यान में रखना होगा।
ओलले सॉडरस्ट्रॉम

11
क्योंकि वे वैकल्पिक हैं। यह डेवलपर के ऊपर है जिन्होंने शून्य या उससे अधिक के संचालन को संभालने के लिए विधि को ठीक से लागू करने के लिए वैकल्पिक तर्कों का उपयोग करने का निर्णय लिया।
किस्वा

@ ओललेसोदरस्ट्रम एक और कारण यह है कि औपचारिक पैरामीटर को संकलन-समय पर एक सरणी में बदल दिया जाता है। इसका मतलब है कि एक सरणी में पास होने से एक ही परिणाम मिलता है। चूंकि संकलन समय पर किसी सरणी की लंबाई ज्ञात नहीं है, इसलिए कम से कम एक तत्व को पारित करने के लिए प्रतिबंध को केवल कॉल करके बाईपास किया जा सकता है someMethod(new SomeType[] { })। यह एक हैक होगा, है ना?
एमसी सम्राट

124

उस सुविधा को varargs कहा जाता है , और यह जावा 5 में शुरू की गई एक विशेषता है। इसका मतलब है कि फ़ंक्शन कई Stringतर्क प्राप्त कर सकता है:

myMethod("foo", "bar");
myMethod("foo", "bar", "baz");
myMethod(new String[]{"foo", "var", "baz"}); // you can even pass an array

फिर, आप Stringएक सरणी के रूप में var का उपयोग कर सकते हैं :

public void myMethod(String... strings){
    for(String whatever : strings){
        // do what ever you want
    }

    // the code above is is equivalent to
    for( int i = 0; i < strings.length; i++){
        // classical for. In this case you use strings[i]
    }
}

यह उत्तर किस्वा और लोरेंजो के ... और ग्रेफिन की टिप्पणी से बहुत अधिक उधार लेता है।


13
जब कोड बाइटकोड को हिट करता है, तो यह एक सरणी है। बाकी सब कुछ सिंटेक्स द्वारा संकलित द्वारा समर्थित है।
डोनल फैलो

यह उत्तर किस्वा और लोरेंजो से बहुत अधिक उधार लेता है अगर मैं संपादन को सही ढंग से पढ़ूं।
मैट मिशेल

3
@ उत्तर को बेहतर बनाने के लिए अपने उत्तर को संपादित करें और इसे अकेले छोड़ने की तुलना में अधिक सही बनाएं। और अगर एक और जवाब आपके सुधार का स्रोत है, तो यह जाता है। कम से कम वह इसके बारे में ईमानदार है (और मुझे लगता है कि उसने उन अन्य उत्तरों को उखाड़ फेंका जो उसकी मदद करते थे ... ठीक है?)।

1
@Will वह ईमानदार है जब मैंने इसे इंगित किया जो काफी ठीक है। तलाश के लिए धन्यवाद।
मैट मिशेल

23

यह वर्गास है :)

चर-लंबाई के तर्कों के लिए लघु संस्करण एक विशेषता है जो विधि को चर संख्या के तर्क (शून्य या अधिक) को स्वीकार करने की अनुमति देता है। वैरगैस के साथ ऐसी विधियाँ बनाना सरल हो गया है जिनके लिए कई प्रकार के तर्कों की आवश्यकता होती है। चर तर्क की सुविधा को जावा 5 में जोड़ा गया है।

वैरगेट्स का सिंटैक्स

एक वैरग को तीन एलिप्सिस (तीन डॉट्स) द्वारा सुरक्षित किया जाता है डेटा प्रकार के बाद, इसका सामान्य रूप है

return_type method_name(data_type ... variableName){
}  

वरग की आवश्यकता

जावा 5 से पहले, मामले में तर्क की चर संख्या की आवश्यकता थी, इसे संभालने के दो तरीके थे

यदि तर्कों की अधिकतम संख्या, एक विधि को छोटा और ज्ञात किया जा सकता है, तो विधि के अतिभारित संस्करण बनाए जा सकते हैं। यदि तर्कों की अधिकतम संख्या एक विधि ले सकती है वह बड़ी या / और अज्ञात थी, तो दृष्टिकोण उन तर्कों को एक सरणी में रखना और उन्हें एक विधि से पारित करना था जो एक पैरामीटर के रूप में सरणी लेता है। ये 2 दृष्टिकोण त्रुटि-प्रवण थे - हर बार मापदंडों की एक सरणी का निर्माण और बनाए रखना मुश्किल - नए तर्क के अलावा एक नई अतिभारित विधि लिखने के परिणामस्वरूप हो सकता है।

वर्गाकार के लाभ

अधिक सरल विकल्प प्रदान करता है। कम कोड के रूप में अतिभारित तरीकों को लिखने की आवश्यकता नहीं है।

वरग का उदाहरण

public class VarargsExample {
 public void displayData(String ... values){
  System.out.println("Number of arguments passed " + values.length);
  for(String s : values){
   System.out.println(s + " ");
  }
 }

 public static void main(String[] args) {
  VarargsExample vObj = new VarargsExample();
  // four args
  vObj.displayData("var", "args", "are", "passed");
  //three args
  vObj.displayData("Three", "args", "passed");
  // no-arg
  vObj.displayData();
 }
}
Output

Number of arguments passed 4
var 
args 
are 
passed 
Number of arguments passed 3
Three 
args 
passed 
Number of arguments passed 0

इस कार्यक्रम से देखा जा सकता है कि विधि के लिए पारित तर्कों की संख्या का पता लगाने के लिए लंबाई का उपयोग यहां किया जाता है। यह संभव है क्योंकि varargs को एक सरणी के रूप में निहित किया गया है। जो भी तर्क पारित किए जाते हैं, वे varargs एक सरणी में संग्रहीत किए जाते हैं, जिसे varargs को दिए गए नाम से संदर्भित किया जाता है। इस कार्यक्रम में सरणी का नाम मान है। यह भी ध्यान दें कि विधि को विभिन्न संख्या के तर्क के साथ कहा जाता है, पहले चार तर्कों के साथ कॉल करें, फिर तीन तर्कों और फिर शून्य तर्कों के साथ। इन सभी कॉल्स को उसी विधि द्वारा नियंत्रित किया जाता है जो वैरगेज़ लेता है।

वार्गर्स के साथ प्रतिबंध

एक विधि में varargs पैरामीटर के साथ अन्य पैरामीटर होना संभव है, हालांकि उस स्थिति में, varargs पैरामीटर को विधि द्वारा घोषित अंतिम पैरामीटर होना चाहिए।

void displayValues(int a, int b, int  values) // OK
   void displayValues(int a, int b, int  values, int c) // compiler error

Varargs के साथ एक और प्रतिबंध यह है कि केवल एक varargs पैरामीटर होना चाहिए।

void displayValues(int a, int b, int  values, int  moreValues) // Compiler error

ओवररोडिंग वैरगेज मेथड्स

यह एक ऐसी विधि को अधिभारित करना संभव है जो वैरैगस पैरामीटर लेती है। वर्गास विधि द्वारा अतिभारित किया जा सकता है -

इसके वैरग पैरामीटर के प्रकार भिन्न हो सकते हैं। अन्य मापदंडों को जोड़कर। ओवररिंग वर्गास विधि का उदाहरण

public class OverloadingVarargsExp {
 // Method which has string vararg parameter
 public void displayData(String ... values){
  System.out.println("Number of arguments passed " + values.length);
  for(String s : values){
   System.out.println(s + " ");
  }
 }

 // Method which has int vararg parameter
 public void displayData(int ... values){
  System.out.println("Number of arguments passed " + values.length);
  for(int i : values){
   System.out.println(i + " ");
  }
 }

 // Method with int vararg and one more string parameter
 public void displayData(String a, int ... values){
  System.out.println(" a " + a);
  System.out.println("Number of arguments passed " + values.length);
  for(int i : values){
   System.out.println(i + " ");
  }
 }

 public static void main(String[] args) {
  OverloadingVarargsExp vObj = new OverloadingVarargsExp();
  // four string args
  vObj.displayData("var", "args", "are", "passed");

  // two int args
  vObj.displayData(10, 20);

  // One String param and two int args
  vObj.displayData("Test", 20, 30);
 }
}
Output

Number of arguments passed 4
var 
args 
are 
passed 

Number of arguments passed 2
10 
20

 a Test
Number of arguments passed 2
20 
30 

वैराग और ओवरलोडिंग अस्पष्टता

कुछ मामलों में कॉल अस्पष्ट हो सकती है, जबकि हमारे पास वर्गास विधि है। एक उदाहरण देखते हैं

public class OverloadingVarargsExp {
 // Method which has string vararg parameter
 public void displayData(String ... values){
  System.out.println("Number of arguments passed " + values.length);
  for(String s : values){
   System.out.println(s + " ");
  }
 }

 // Method which has int vararg parameter
 public void displayData(int ... values){
  System.out.println("Number of arguments passed " + values.length);
  for(int i : values){
   System.out.println(i + " ");
  }
 }

 public static void main(String[] args) {
  OverloadingVarargsExp vObj = new OverloadingVarargsExp();
  // four string args
  vObj.displayData("var", "args", "are", "passed");

  // two int args
  vObj.displayData(10, 20);

  // This call is ambiguous
  vObj.displayData();
 }
}

इस प्रोग्राम में जब हम किसी भी पैरामीटर के बिना डिस्प्लेडैट () विधि के लिए कॉल करते हैं तो यह त्रुटि फेंकता है, क्योंकि कंपाइलर सुनिश्चित नहीं है कि यह विधि कॉल के लिए है displayData(String ... values)या नहींdisplayData(int ... values)

उसी तरह अगर हम तरीकों जहां एक है अतिभारित है varargएक प्रकार की विधि और किसी अन्य विधि का एक पैरामीटर और है vararg, एक ही प्रकार के पैरामीटर तो भी हम अस्पष्टता है - के रूप में ऍक्स्प - displayData(int ... values)औरdisplayData(int a, int ... values)

इन दो अतिभारित तरीकों में हमेशा अस्पष्टता होगी।


15

यह varargs (वेरिएबल नंबर आर्ग्युमेंट्स) पास करने का जावा तरीका है ।

यदि आप C से परिचित हैं, तो यह ...सिंटैक्स के समान है जो इसे printfफ़ंक्शन का उपयोग करता है:

int printf(const char * format, ...);

लेकिन एक प्रकार में सुरक्षित फैशन: प्रत्येक तर्क को निर्दिष्ट प्रकार (आपके नमूने में, वे सभी होने चाहिए String) का अनुपालन करना होगा ।

यह एक सरल नमूना है कि आप वर्गास का उपयोग कैसे कर सकते हैं :

class VarargSample {

   public static void PrintMultipleStrings(String... strings) {
      for( String s : strings ) {
          System.out.println(s);
      }
   }

   public static void main(String[] args) {
      PrintMultipleStrings("Hello", "world");
   }
}

...तर्क वास्तव में एक सरणी है, तो आप एक गुजारें सकता है String[]पैरामीटर के रूप में।


11

तर्कबद्ध रूप से, यह वाक्यविन्यास चीनी का एक उदाहरण है, क्योंकि इसे एक सरणी के रूप में लागू किया जाता है (जिसका अर्थ यह नहीं है कि यह बेकार है) - मैं इसे स्पष्ट रखने के लिए एक सरणी पास करना पसंद करता हूं, और दिए गए प्रकार के सरणियों के साथ तरीकों की घोषणा भी करता हूं। एक जवाब के बजाय, हालांकि।


5

इसके अलावा कुछ प्रकाश डालने के लिए, यह जानना महत्वपूर्ण है कि var-arg पैरामीटर एक तक सीमित हैं और आपके पास कई var-art params नहीं हो सकते हैं। उदाहरण के लिए यह इल्लीगल है:

public void myMethod(String... strings, int ... ints){
// method body
}


2

एंड्रॉइड AsyncTask में सबसे प्रसिद्ध तरीकों में से एक में मौजूद तीन डॉट्स के उपयोग का एक स्पष्ट उदाहरण देखने के लिए एक सामान्य तरीका है (आज का उपयोग RXJAVA के कारण बहुत अधिक नहीं किया गया है, Google आर्किटेक्चर घटकों का उल्लेख नहीं करने के लिए) आप इस शब्द को खोजने के लिए हजारों उदाहरण पा सकते हैं, और समझने का सबसे अच्छा तरीका और कभी नहीं भूल सकते हैं कि तीन बिंदुओं का अर्थ यह है कि वे एक ... संदेह व्यक्त करते हैं ... जैसे आम भाषा में। अर्थात् यह स्पष्ट नहीं है कि कितने मापदंडों को पारित किया जाना है, 0 हो सकता है, 1 हो सकता है अधिक (एक सरणी) हो सकता है ...


1

String... के समान है String[]

import java.lang.*;

public class MyClassTest {

    //public static void main(String... args) { 

    public static void main(String[] args) {
        for(String str: args) {
            System.out.println(str);
        }
    }
}

1
अगर String...ऐसा ही है String[], तो क्या आप ऐसा नहीं कह सकते?
स्कॉट हंटर

8
तकनीकी रूप से सच नहीं है क्योंकि String[]एक तर्क (कम से कम एक खाली सरणी) की आवश्यकता होती String...है, जबकि ऊपर (इसका उत्तर नहीं देखें)।
ऑरेल

0

अन्य अच्छी तरह से लिखे गए उत्तरों में जोड़कर, varagrsमुझे उपयोगी पाया गया वह यह है कि जब मैं एक विधि को पैरामीटर प्रकार के रूप में सरणी के साथ कहता हूं, तो यह एक सरणी बनाने के दर्द को दूर करता है; तत्वों को जोड़ें और फिर भेजें। इसके बजाय, मैं सिर्फ उतने ही मूल्यों के साथ विधि को कॉल कर सकता हूं जितना मैं चाहता हूं; शून्य से कई तक।


0
  • इसका अर्थ है एक ही डेटा प्रकार का शून्य या एकाधिक पैरामीटर।
  • यह कंस्ट्रक्टर या फ़ंक्शन का अंतिम पैरामीटर होना चाहिए।
  • हम संबंधित कंस्ट्रक्टर या फ़ंक्शन में इस प्रकार के केवल एक पैरामीटर रख सकते हैं।

उदाहरण 1:

public class quest1 {

    public quest1(String... mynum) {
        System.out.println("yee haa");
    }

    public static void main(String[] args) {
        quest1 q=new quest1();

        quest1 q1=new quest1("hello");

    }
}

उदाहरण 2:

public class quest1 {

    public quest1(int... at) {
        System.out.println("yee haa");
    }

    public quest1(String... at) {
        System.out.println("yee haa");
    }

    public static void main(String[] args) {
        quest1 q=new quest1("value");

        quest1 q1=new quest1(1);

    }

    public void name(String ... s) {

    }
}

उत्पादन:

यी हा

यी हा


-1

सिंटैक्स: (ट्रिपल डॉट ...) -> मतलब हम एक तर्क में शून्य या अधिक ऑब्जेक्ट्स जोड़ सकते हैं या किसी प्रकार की ऑब्जेक्ट पास कर सकते हैं।

public static void main(String[] args){}
public static void main(String... args){}

परिभाषा: 1) वस्तु ... तर्क केवल वस्तुओं की एक सरणी के लिए एक संदर्भ है।

2) ('स्ट्रिंग []' या स्ट्रिंग ...) यह किसी भी स्ट्रिंग ऑब्जेक्ट्स को संभालने में सक्षम हो सकता है। आंतरिक रूप से यह एक प्रकार का संदर्भ प्रकार ऑब्जेक्ट का उपयोग करता है।

i.e. Suppose we pass an Object array to the ... argument - will the resultant argument value be a two-dimensional array - because an Object[] is itself an Object:

3) यदि आप किसी एकल तर्क के साथ विधि को कॉल करना चाहते हैं और यह एक सरणी के रूप में होता है, तो आपको इसे स्पष्ट रूप से लपेटना होगा

another. method(new Object[]{array}); 
OR 
method((Object)array), which will auto-wrap.

अनुप्रयोग: इसका उपयोग प्रमुख रूप से तब किया जाता है जब तर्कों की संख्या गतिशील होती है (तर्क की संख्या रनटाइम पर पता होती है) और ओवरराइडिंग में। सामान्य नियम - विधि में हम किसी भी प्रकार और किसी भी तर्क को पारित कर सकते हैं। हम किसी भी विशिष्ट तर्क से पहले ऑब्जेक्ट (...) तर्क नहीं जोड़ सकते। अर्थात

void m1(String ..., String s) this is a wrong approach give syntax error.
void m1(String s, String ...); This is a right approach. Must always give last order prefernces.   
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.