parametros - ¿Puedo pasar una matriz como argumentos a un método con argumentos variables en Java?
pasar un arreglo de objetos como parametro en java (5)
El tipo subyacente de una function(Object... args)
método variadic function(Object... args)
es function(Object[] args)
. Sun agregó varargs de esta manera para preservar la compatibilidad hacia atrás.
Por lo tanto, solo debe poder extraVar
a args
y llamar a String.format(format, args)
.
Me gustaría poder crear una función como:
class A {
private String extraVar;
public String myFormat(String format, Object ... args){
return String.format(format, extraVar, args);
}
}
El problema aquí es que args
se trata como Object[]
en el método myFormat
, y por lo tanto es un argumento único para String.format
, mientras que me gustaría que cada Object
en args
se pasara como un nuevo argumento. Dado que String.format
también es un método con argumentos variables, esto debería ser posible.
Si esto no es posible, ¿existe un método como String.format(String format, Object[] args)
? En ese caso, podría extraVar
a args
utilizando una nueva matriz y pasarlo a ese método.
Está bien pasar una matriz, de hecho, equivale a lo mismo
String.format("%s %s", "hello", "world!");
es lo mismo que
String.format("%s %s", new Object[] { "hello", "world!"});
Es solo azúcar sintáctica: el compilador convierte el primero en segundo, ya que el método subyacente está esperando una matriz para el parámetro vararg .
Ver
Estaba teniendo el mismo problema.
String[] arr= new String[] { "A", "B", "C" };
Object obj = arr;
Y luego pasó el obj como argumento varargs. Funcionó.
Sí, una T...
es solo un azúcar sintáctico para una T[]
.
JLS 8.4.1 Parámetros de formato
El último parámetro formal en una lista es especial; puede ser un parámetro de aridad variable , indicado por una elipsis que sigue al tipo.
Si el último parámetro formal es un parámetro de aridad variable de tipo
T
, se considera que define un parámetro formal de tipoT[]
. El método es entonces un método de aridad variable . De lo contrario, es un método de aridad fija . Las invocaciones de un método de aridad variable pueden contener más expresiones de argumentos reales que parámetros formales. Se evaluarán todas las expresiones de argumentos reales que no correspondan a los parámetros formales que preceden al parámetro arity variable y los resultados se almacenarán en una matriz que se pasará a la invocación del método.
Aquí hay un ejemplo para ilustrar:
public static String ezFormat(Object... args) {
String format = new String(new char[args.length])
.replace("/0", "[ %s ]");
return String.format(format, args);
}
public static void main(String... args) {
System.out.println(ezFormat("A", "B", "C"));
// prints "[ A ][ B ][ C ]"
}
Y sí, el método main
anterior es válido, porque nuevamente, String...
es solo String[]
. Además, como las matrices son covariantes, una String[]
es un Object[]
, por lo que también puede llamar a ezFormat(args)
cualquier forma.
Ver también
Varargs gotchas # 1: pasando null
La forma en que se resuelven los varargs es bastante complicada y, a veces, hace cosas que pueden sorprenderte.
Considera este ejemplo:
static void count(Object... objs) {
System.out.println(objs.length);
}
count(null, null, null); // prints "3"
count(null, null); // prints "2"
count(null); // throws java.lang.NullPointerException!!!
Debido a la forma en que se resuelven los varargs, la última instrucción se invoca con objs = null
, lo que por supuesto causaría la objs.length
NullPointerException
con objs.length
. Si desea dar un argumento null
a un parámetro varargs, puede hacer una de las siguientes acciones:
count(new Object[] { null }); // prints "1"
count((Object) null); // prints "1"
Preguntas relacionadas
La siguiente es una muestra de algunas de las preguntas que las personas han hecho al tratar con varargs:
- error con varargs y sobrecarga?
- Cómo trabajar con varargs y reflexión.
- El método más específico con coincidencias de aridad fija / variable (varargs)
Vararg Gotchas # 2: añadiendo argumentos extra
Como has descubierto, lo siguiente no "funciona":
String[] myArgs = { "A", "B", "C" };
System.out.println(ezFormat(myArgs, "Z"));
// prints "[ [Ljava.lang.String;@13c5982 ][ Z ]"
Debido a la forma en que funcionan los varargs, ezFormat
obtiene 2 argumentos, el primero es un String[]
, el segundo es un String
. Si está pasando una matriz a varargs, y desea que sus elementos se reconozcan como argumentos individuales, y también necesita agregar un argumento adicional, no tiene más remedio que crear otra matriz que acomode el elemento adicional.
Aquí hay algunos métodos útiles de ayuda:
static <T> T[] append(T[] arr, T lastElement) {
final int N = arr.length;
arr = java.util.Arrays.copyOf(arr, N+1);
arr[N] = lastElement;
return arr;
}
static <T> T[] prepend(T[] arr, T firstElement) {
final int N = arr.length;
arr = java.util.Arrays.copyOf(arr, N+1);
System.arraycopy(arr, 0, arr, 1, N);
arr[0] = firstElement;
return arr;
}
Ahora puedes hacer lo siguiente:
String[] myArgs = { "A", "B", "C" };
System.out.println(ezFormat(append(myArgs, "Z")));
// prints "[ A ][ B ][ C ][ Z ]"
System.out.println(ezFormat(prepend(myArgs, "Z")));
// prints "[ Z ][ A ][ B ][ C ]"
Varargs Gotchas # 3: pasando una serie de primitivas
No "funciona":
int[] myNumbers = { 1, 2, 3 };
System.out.println(ezFormat(myNumbers));
// prints "[ [I@13c5982 ]"
Varargs solo funciona con tipos de referencia. Autoboxing no se aplica a la matriz de primitivos. Los siguientes trabajos:
Integer[] myNumbers = { 1, 2, 3 };
System.out.println(ezFormat(myNumbers));
// prints "[ 1 ][ 2 ][ 3 ]"
jasonmp85 tiene razón al pasar una matriz diferente a String.format
. El tamaño de una matriz no se puede cambiar una vez que se construye, por lo que tendría que pasar una nueva matriz en lugar de modificar la existente.
Object newArgs = new Object[args.length+1];
System.arraycopy(args, 0, newArgs, 1, args.length);
newArgs[0] = extraVar;
String.format(format, extraVar, args);