ChatGPT解决这个技术问题 Extra ChatGPT

What do 3 dots next to a parameter type mean in Java?

What do the 3 dots following String in the following method mean?

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

M
M. Justin

It means that zero or more String objects (or a single array of them) may be passed as the argument(s) for that method.

See the "Arbitrary Number of Arguments" section here: http://java.sun.com/docs/books/tutorial/java/javaOO/arguments.html#varargs

In your example, you could call it as any of the following:

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

Important Note: The argument(s) passed in this way is always an array - even if there's just one. Make sure you treat it that way in the method body.

Important Note 2: The argument that gets the ... must be the last in the method signature. So, myMethod(int i, String... strings) is okay, but myMethod(String... strings, int i) is not okay.

Thanks to Vash for the clarifications in his comment.


I wish if this would have worked too. myMethod("one","two","three", new String[] {"a","b","c""});
Why are you allowed to give the method 0 parameters? That will most likely lead to ArrayIndexOutOfBoundsException. Now you always have to take that case into consideration.
Because they're optional. It's up to the developer who decided to use optional arguments to properly implement the method to handle having zero or more of them.
@OlleSöderström Another reason is that the formal parameter is converted to be an array at compile-time. That means that passing in an array yields the same result. Since an array's length is not known at compile time, the restriction to pass at least one element could be bypassed by simply calling someMethod(new SomeType[] { }). That would be a hack, wouldn't it?
Are there languages where the variadic arguments are not the last and further non-kw args are possible when no confusion can happen?
C
Community

That feature is called varargs, and it's a feature introduced in Java 5. It means that function can receive multiple String arguments:

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

Then, you can use the String var as an array:

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

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

This answer borrows heavily from kiswa's and Lorenzo's... and also from Graphain's comment.


When the code hits the bytecode, it is an array. Everything else is syntax supported just by the compiler.
This answer borrows heavily from kiswa's and Lorenzo's if I read the edits correctly.
@Graph 'tis better to edit your answer and make it more correct than to leave it alone. And if another answer is the source of your improvement, so it goes. At least he's honest about it (and I assume he upvoted the other answers that helped him... right?).
@Will he's honest after I pointed it out which is fine enough. Thanks for looking.
s
shanwije

It's Varargs :)

The varargs short for variable-length arguments is a feature that allows the method to accept variable number of arguments (zero or more). With varargs it has become simple to create methods that need to take a variable number of arguments. The feature of variable argument has been added in Java 5.

Syntax of varargs

A vararg is secified by three ellipsis (three dots) after the data type, its general form is

return_type method_name(data_type ... variableName){
}  

Need for varargs

Prior to Java 5, in case there was a need of variable number of arguments, there were two ways to handle it

If the max number of arguments, a method can take was small and known, then overloaded versions of the method could be created. If the maximum number of arguments a method could take was large or/and unknown then the approach was to put those arguments in an array and pass them to a method which takes array as a parameter. These 2 approaches were error-prone - constructing an array of parameters every time and difficult to maintain - as the addition of new argument may result in writing a new overloaded method.

Advantages of varargs

Offers a much simpler option. Less code as no need to write overloaded methods.

Example of varargs

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

It can be seen from the program that length is used here to find the number of arguments passed to the method. It is possible because varargs are implicitly passed as an array. Whatever arguments are passed as varargs are stored in an array which is referred by the name given to varargs. In this program array name is values. Also note that method is called with different number of argument, first call with four arguments, then three arguments and then with zero arguments. All these calls are handled by the same method which takes varargs.

Restriction with varargs

It is possible to have other parameters with varargs parameter in a method, however in that case, varargs parameter must be the last parameter declared by the method.

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

Another restriction with varargs is that there must be only one varargs parameter.

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

Overloading varargs Methods

It is possible to overload a method that takes varargs parameter. Varargs method can be overloaded by -

Types of its vararg parameter can be different. By adding other parameters. Example of overloading varargs method

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 

Varargs and overloading ambiguity

In some cases call may be ambiguous while we have overloaded varargs method. Let's see an example

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();
 }
}

In this program when we make a call to displayData() method without any parameter it throws error, because compiler is not sure whether this method call is for displayData(String ... values) or displayData(int ... values)

Same way if we have overloaded methods where one has the vararg method of one type and another method has one parameter and vararg parameter of the same type, then also we have the ambiguity - As Exp - displayData(int ... values) and displayData(int a, int ... values)

These two overloaded methods will always have ambiguity.


l
lornova

This is the Java way to pass varargs (variable number arguments).

If you are familiar with C, this is similar to the ... syntax used it the printf function:

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

but in a type safe fashion: every argument has to comply with the specified type (in your sample, they should be all String).

This is a simple sample of how you can use varargs:

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");
   }
}

The ... argument is actually an array, so you could pass a String[] as the parameter.


M
MichaelS

Arguably, it is an example of syntactic sugar, since it is implemented as an array anyways (which doesn't mean it's useless) - I prefer passing an array to keep it clear, and also declare methods with arrays of given type. Rather an opinion than an answer, though.


M
Mr.Q

Also to shed some light, it is important to know that var-arg parameters are limited to one and you can't have several var-art params. For example this is illigal:

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

Ε
Ε Г И І И О

Just think of it as the keyword params in C#, if you are coming from that background :)


I am a C# programmer.
t
trocchietto

A really common way to see a clear example of the use of the three dots it is present in one of the most famous methods in android AsyncTask ( that today is not used too much because of RXJAVA, not to mention the Google Architecture components), you can find thousands of examples searching for this term, and the best way to understand and never forget anymore the meaning of the three dots is that they express a ...doubt... just like in the common language. Namely it is not clear the number of parameters that have to be passed, could be 0, could be 1 could be more( an array)...


P
PhantomReference

Adding to the other well-written answers, an advantage of varagrs I found useful is that, when I call a method with array as a parameter type, it takes away the pain of creating an array; add elements and then send it. Instead, I can just call the method with as many values as I want; from zero to many.


V
Vishal Sheth

Syntax: (Triple dot ... ) --> Means we can add zero or more objects pass in an arguments or pass an array of type object.

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

Definition: 1) The Object ... argument is just a reference to an array of Objects.

2) ('String []' or String ... ) It can able to handle any number of string objects. Internally it uses an array of reference type object.

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) If you want to call the method with a single argument and it happens to be an array, you have to explicitly wrap it in

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

Application: It majorly used when the number of arguments is dynamic(number of arguments know at runtime) and in overriding. General rule - In the method we can pass any types and any number of arguments. We can not add object(...) arguments before any specific arguments. i.e.

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.