argumentos - ¿Cuándo usas varargs en Java?
vararg kotlin (8)
En el documento Java de Var-Args está bastante claro el uso de var args:
http://docs.oracle.com/javase/1.5.0/docs/guide/language/varargs.html
sobre el uso dice:
"Entonces, ¿cuándo deberías usar varargs? Como cliente, debes aprovecharlos siempre que la API los ofrezca. Los usos importantes en las API principales incluyen la reflexión, el formato de mensajes y las nuevas instalaciones de impresión. Como diseñador de API, debes usarlos con moderación, solo cuando el beneficio es realmente convincente. En términos generales, no debe sobrecargar un método varargs, o será difícil para los programadores descubrir qué sobrecarga se llama ".
Tengo miedo de varargs. No sé para qué usarlos.
Además, se siente peligroso dejar que las personas pasen tantos argumentos como quieran.
¿Cuál es un ejemplo de contexto que sería un buen lugar para usarlos?
Tengo un miedo relacionado con varargs, también:
Si la persona que llama transfiere una matriz explícita al método (a diferencia de múltiples parámetros), recibirá una referencia compartida a esa matriz.
Si necesita almacenar esta matriz internamente, es posible que desee clonarla primero para evitar que la persona que llama pueda cambiarla más tarde.
Object[] args = new Object[] { 1, 2, 3} ;
varArgMethod(args); // not varArgMethod(1,2,3);
args[2] = "something else"; // this could have unexpected side-effects
Si bien esto no es realmente diferente de pasar en cualquier tipo de objeto cuyo estado podría cambiar más adelante, dado que la matriz es generalmente (en el caso de una llamada con múltiples argumentos en lugar de una matriz) una nueva creada internamente por el compilador que puede uso, este es un comportamiento inesperado.
Una buena regla empírica sería:
"Use varargs para cualquier método (o constructor) que necesite una matriz de T (cualquiera que sea el tipo T) como entrada".
Esto facilitará las llamadas a estos métodos (no es necesario hacer una new T[]{...}
).
Puede extender esta regla para incluir métodos con un argumento de List<T>
, siempre que este argumento sea solo para entrada (es decir, la lista no sea modificada por el método).
Además, me abstendría de usar f(Object... args)
porque se desliza hacia una forma de programación con API poco claras.
En términos de ejemplos, lo he usado en DesignGridLayout , donde puedo agregar varios JComponent
en una sola llamada:
layout.row().grid(new JLabel("Label")).add(field1, field2, field3);
En el código anterior, el método add () se define como add(JComponent... components)
.
Finalmente, la implementación de tales métodos debe tener en cuenta el hecho de que se puede invocar con un vararg vacío. Si quieres imponer al menos un argumento, entonces tienes que usar un truco feo como:
void f(T arg1, T... args) {...}
Considero que este truco es feo porque la implementación del método será menos directa que tener simplemente T... args
en su lista de argumentos.
Espera esto ayuda a aclarar el punto sobre varargs.
Utilizo varargs con frecuencia para constructores que pueden tomar algún tipo de objeto de filtro. Por ejemplo, una gran parte de nuestro sistema basado en Hadoop se basa en un Mapper que maneja la serialización y deserialización de elementos a JSON, y aplica una cantidad de procesadores que toman un elemento de contenido y lo modifican y lo devuelven, o devuelven null rechazar.
Utilizo varargs con frecuencia para dar salida a los registros para fines de depuración.
Casi todas las clases de mi aplicación tienen un método debugPrint ():
private void debugPrint(Object... msg) {
for (Object item : msg) System.out.print(item);
System.out.println();
}
Luego, dentro de los métodos de la clase, tengo llamadas como las siguientes:
debugPrint("for assignment ", hwId, ", student ", studentId, ", question ",
serialNo, ", the grade is ", grade);
Cuando estoy satisfecho de que mi código funciona, comente el código en el método debugPrint () para que los registros no contengan demasiada información extraña y no deseada, pero puedo dejar las llamadas individuales a debugPrint () sin comentario. Más adelante, si encuentro un error, simplemente elimino el código de debugPrint () y todas mis llamadas a debugPrint () se reactivan.
Por supuesto, podría fácilmente evitar a las varargs y hacer lo siguiente en su lugar:
private void debugPrint(String msg) {
System.out.println(msg);
}
debugPrint("for assignment " + hwId + ", student " + studentId + ", question "
+ serialNo + ", the grade is " + grade);
Sin embargo, en este caso, cuando comente el código debugPrint (), el servidor todavía tiene que pasar por la dificultad de concatenar todas las variables en cada llamada a debugPrint (), aunque no se haga nada con la cadena resultante. Sin embargo, si uso varargs, el servidor solo tiene que ponerlos en una matriz antes de darse cuenta de que no los necesita. Se ahorra mucho tiempo.
Varargs es la característica agregada en la versión 1.5 de Java.
¿Por qué usar esto?
- ¿Qué pasa si no conoce la cantidad de argumentos para pasar por un método?
- ¿Qué pasa si quieres pasar una cantidad ilimitada de argumentos a un método?
¿Cómo funciona esto?
Crea una matriz con los argumentos dados y pasa la matriz al método.
Ejemplo:
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 );
}
}
Salida:
2
suma es 12
3
suma es 21
Varargs se puede usar cuando no estamos seguros sobre la cantidad de argumentos que se pasarán en un método. Crea un conjunto de parámetros de longitud no especificada en el fondo y dicho parámetro se puede tratar como una matriz en tiempo de ejecución.
Si tenemos un método que está sobrecargado para aceptar diferentes números de parámetros, entonces en lugar de sobrecargar el método en diferentes momentos, simplemente podemos usar el concepto varargs.
Además, cuando el tipo de parámetros va a variar, el uso de "Object ... test" simplificará mucho el código.
Por ejemplo:
public int calculate(int...list) {
int sum = 0;
for (int item : list) {
sum += item;
}
return sum;
}
Aquí indirectamente una matriz de tipo int (lista) se pasa como parámetro y se trata como una matriz en el código.
Para una mejor comprensión, siga este enlace (me ayudó mucho a comprender este concepto claramente): http://www.javadb.com/using-varargs-in-java
PD: Incluso yo tenía miedo de usar varargs cuando no lo sabía. Pero ahora estoy acostumbrado. Como se dice: "Nos aferramos a lo conocido, tememos a lo desconocido", así que solo úsalo tanto como puedas y tú también comenzarás a agradarlo :)
Los varargs son útiles para cualquier método que necesite tratar con una cantidad indeterminada de objetos . Un buen ejemplo es String.format
. La cadena de formato puede aceptar cualquier cantidad de parámetros, por lo que necesita un mecanismo para pasar en cualquier cantidad de objetos.
String.format("This is an integer: %d", myInt);
String.format("This is an integer: %d and a string: %s", myInt, myString);