Java, 3 puntos en parámetros


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

public void myMethod(String... strings){
    // method body
}
Author: Adarsh H S, 2010-07-01

9 answers

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, podría llamarlo como cualquiera de los siguientes:

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

Nota importante: El(los) argumento (s) pasado (s) de esta manera es siempre un array - incluso si solo hay uno. Asegúrate de tratarlo así. forma en el cuerpo del método.

Nota importante 2: El argumento que obtiene el ... debe ser el último en la firma del método. Entonces, 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.

 831
Author: kiswa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-02-16 17:13:10

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, puede usar el var String 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 prestado en gran medida de kiswa y Lorenzo... y también del comentario de Graphain.

 102
Author: Cristian,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-01-18 19:39:46

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

Si está familiarizado con C, esto es similar a la sintaxis ... utilizada la función printf:

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

Pero de una manera segura de tipo: cada argumento tiene que cumplir con el tipo especificado (en su muestra, deben ser todos String).

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

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

 12
Author: Wizard79,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-07-22 07:42:36

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
Author: MichaelS,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-05-11 10:35:18

Es Varargs :)

La abreviatura de varargs para argumentos de longitud variable es una característica que permite al método aceptar un número variable de argumentos (cero o más). Con varargs se ha vuelto sencillo crear métodos que necesitan tomar un número variable de argumentos. La característica de argumento variable se ha añadido en Java 5.

Sintaxis de varargs

Un vararg se escifica por tres puntos suspensivos (tres puntos) después del tipo de datos, su la 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 número variable de argumentos, había dos maneras de manejarlo

Si el número máximo de argumentos, un método puede tomar era pequeño y conocido, entonces 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 / y desconocido, entonces el enfoque era poner esos argumentos en una matriz y pasarlos a un método que toma array 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 resultar en la escritura de un nuevo método sobrecargado.

Ventajas de varargs

Ofrece una opción mucho más sencilla. Menos código ya que no hay necesidad de 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 en el programa que la longitud se utiliza aquí para encontrar la número de argumentos pasados al método. Es posible porque los varargs se pasan implícitamente como una matriz. Cualquier argumento que se pase como varargs se almacena en una matriz que se refiere por el nombre dado a varargs. En esta matriz de programas el nombre es values. También tenga en cuenta que el método se llama con un número diferente de argumentos, primero llame 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 solo debe haber un parámetro varargs.

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

Sobrecarga de métodos varargs

Es posible sobrecargar un método que toma el parámetro varargs. Método Varargs puede ser sobrecargado por -

Los tipos de su parámetro vararg pueden ser diferentes. Añadiendo 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 and overloading ambiguity

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 hacemos una llamada al método displayData () sin ningún parámetro arroja un error, porque el compilador no está seguro de si este método la llamada es para displayData(String ... values) o displayData(int ... values)

Misma manera si tenemos métodos sobrecargados donde uno tiene la vararg método de uno 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.

 10
Author: SIW,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-23 06:32:18

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

public void myMethod(String... strings, int ... ints){
// method body
}
 4
Author: NԀƎ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-05 17:06:38

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

 3
Author: Ε Г И І И О,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-06-29 05:35:40

String... es lo mismo que 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);

        }
        }
        }
 2
Author: Uddhav Gautam,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-19 18:14:51

Una forma muy común de ver un claro ejemplo del uso de los tres puntos está presente en uno de los métodos más famosos en android AsyncTask (que hoy en día no se usa demasiado debido a RXJAVA, por no hablar de los componentes de la Arquitectura de Google), se pueden encontrar miles de ejemplos buscando este término, y la mejor manera de entender y nunca olvidar más el significado de los tres puntos es que expresan a ...duda... como en el lenguaje común. Es decir, no es clear el número de parámetros que se deben pasar, podría ser 0, podría ser 1 podría ser más (una matriz)...

 1
Author: trocchietto,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-06-29 09:35:35