varargs pasar parametros parametro opcionales objetos indefinidos como arreglo argumentos java arrays backwards-compatibility variadic-functions

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 tipo T[] . 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:

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