Pregunta Java, 3 puntos en parámetros


¿Qué significan los 3 puntos en el siguiente método?

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

662
2017-07-01 14:27


origen


Respuestas:


Significa que se pueden pasar cero o más objetos String (o una matriz de ellos) como argumento (s) para ese método.

Vea la sección "Número arbitrario de argumentos" aquí: http://java.sun.com/docs/books/tutorial/java/javaOO/arguments.html#varargs

En su ejemplo, puede llamarlo de cualquiera de los siguientes:

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

Nota IMPORTANTE: El argumento (s) pasado (s) de esta manera siempre es una matriz, incluso si solo hay una. Asegúrate de tratarlo de esa manera en el cuerpo del método.

Nota importante 2: El argumento que obtiene el ... debe ser el último en la firma del método. Asi que, myMethod(int i, String... strings) está bien, pero myMethod(String... strings, int i) no está bien

Gracias a Vash por las aclaraciones en su comentario.


809
2017-07-01 14:32



Esa característica se llama varargs, y es una característica introducida en Java 5. Significa que la función puede recibir múltiples String argumentos:

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

Entonces, puedes usar el String var como una matriz:

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]
    }
}

Esta respuesta toma mucho de kiswa y Lorenzo ... y también del comentario de Graphain.


101
2017-07-01 14:30



Esta es la forma de pasar Java varargs (argumentos de número variable).

Si está familiarizado con C, esto es similar al ... sintaxis lo usó printf función:

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

pero de una manera segura: cada argumento tiene que cumplir con el tipo especificado (en tu muestra, deberían ser todos String)

Esta es una muestra simple de cómo puedes usar 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");
   }
}

los ... argumento es en realidad una matriz, por lo que podría pasar un String[] como el parámetro.


12
2017-07-01 14:38



Podría decirse que es un ejemplo de azúcar sintáctica, ya que se implementa como una matriz de todos modos (lo que no significa que sea inútil) - Prefiero pasar una matriz para mantenerlo claro, y también declarar métodos con matrices de un tipo dado. Más bien una opinión que una respuesta, sin embargo.


10
2018-05-11 10:35



Es Varargs  :)

El corto varargs para argumentos de longitud variable es una característica que permite que el método acepte un número variable de argumentos (cero o más). Con varargs se ha vuelto simple crear métodos que necesitan tomar una cantidad variable de argumentos. La característica del argumento variable se ha agregado en Java 5.

Sintaxis de varargs

Un vararg está seccionado por tres elipsis (tres puntos) después del tipo de datos, su forma general es

return_type method_name(data_type ... variableName){
}  

Necesidad de varargs

Antes de Java 5, en caso de que hubiera una necesidad de una cantidad variable de argumentos, había dos formas de manejarlo

Si la cantidad máxima de argumentos que un método puede tomar es pequeña y conocida, se podrían crear versiones sobrecargadas del método. Si el número máximo de argumentos que un método podría tomar era grande o desconocido, el enfoque consistía en poner esos argumentos en una matriz y pasarlos a un método que toma una matriz como parámetro. Estos 2 enfoques eran propensos a errores, construyendo una matriz de parámetros cada vez y difíciles de mantener, ya que la adición de un nuevo argumento puede dar como resultado la escritura de un nuevo método sobrecargado.

Ventajas de varargs

Ofrece una opción mucho más simple. Menos código ya que no es necesario escribir métodos sobrecargados.

Ejemplo de 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

Se puede ver desde el programa que la longitud se usa aquí para encontrar la cantidad de argumentos pasados ​​al método. Es posible porque varargs se pasan implícitamente como una matriz. Cualquier argumento que se pase como varargs se almacena en una matriz a la que se hace referencia por el nombre dado a varargs. En este programa, el nombre de la matriz es valores. También tenga en cuenta que se llama al método con diferente número de argumentos, primera llamada con cuatro argumentos, luego tres argumentos y luego con cero argumentos. Todas estas llamadas son manejadas por el mismo método que toma varargs.

Restricción con varargs

Es posible tener otros parámetros con el parámetro varargs en un método, sin embargo, en ese caso, el parámetro varargs debe ser el último parámetro declarado por el método.

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

Otra restricción con varargs es que debe haber solo un parámetro varargs.

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

Sobrecarga de los métodos varargs

Es posible sobrecargar un método que toma el parámetro varargs. El método de Varargs puede sobrecargarse mediante:

Los tipos de su parámetro vararg pueden ser diferentes. Al agregar otros parámetros Ejemplo de sobrecarga del método varargs

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 y sobrecarga de ambigüedad

En algunos casos, la llamada puede ser ambigua, mientras que hemos sobrecargado el método varargs. Veamos un ejemplo

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

En este programa cuando realizamos una llamada al método displayData () sin ningún parámetro arroja un error, porque el compilador no está seguro de si esta llamada a método es para displayData(String ... values) o displayData(int ... values)

De la misma manera si tenemos métodos sobrecargados donde uno tiene el vararg método de un tipo y otro método tiene un parámetro y vararg parámetro del mismo tipo, entonces también tenemos la ambigüedad - Como Exp - displayData(int ... values) y displayData(int a, int ... values)

Estos dos métodos sobrecargados siempre tendrán ambigüedad.


8
2018-01-30 04:50



También para arrojar algo de luz, es importante saber que los parámetros var-arg están limitados a uno y que no se pueden tener varios parametros var-art. Por ejemplo, esto es illigal:

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

4
2018-01-05 17:06



Solo piense en ello como la palabra clave params en C #, si vienes de ese fondo :)


3
2018-06-29 05:35