indefinidos - parametros dinamicos java
¿Por qué no se pasa foo(1,2,3) al método varargs foo(objeto...) como un entero (5)
En el caso de llamar a foo(1,2,3);
el compilador (en este caso javac
) genera el código foo(new Object[]{new Integer(1), new Integer(2), new Integer(3)})
.
javac
aplica las reglas para Varargs y Varargs . El compilador genera una matriz de Object
porque Object...
significa Object[]
. Por lo tanto, la bar
no es una instancia de Integer[]
. Solo es azúcar sintáctica.
Por favor, tenga en cuenta las siguientes líneas de código:
public static void main(String[] args) {
foo(1,2,3);
System.out.println("-------------------------------------");
foo(new Integer(1), new Integer(2), new Integer(3));
System.out.println("-------------------------------------");
foo(new Integer[]{1,2,3});
System.out.println("-------------------------------------");
foo(new Integer[] {new Integer(1), new Integer(2), new Integer(3)});
}
public static void foo(Object... bar) {
System.out.println("bar instanceof Integer[]:/t" + (bar instanceof Integer[]));
System.out.println("bar[0] instanceof Integer:/t" + (bar[0] instanceof Integer));
System.out.println("bar.getClass().isArray():/t" + bar.getClass().isArray());
}
La salida de este fragmento de código es:
bar instanceof Integer[]: false
bar[0] instanceof Integer: true
bar.getClass().isArray(): true
-------------------------------------
bar instanceof Integer[]: false
bar[0] instanceof Integer: true
bar.getClass().isArray(): true
-------------------------------------
bar instanceof Integer[]: true
bar[0] instanceof Integer: true
bar.getClass().isArray(): true
-------------------------------------
bar instanceof Integer[]: true
bar[0] instanceof Integer: true
bar.getClass().isArray(): true
¡Y esto me confunde un poco! No entiendo por qué en el caso de foo(1,2,3)
el término bar instanceof Integer[]
es falso.
Si en estos casos la barra no es una instancia de Integer[]
¿de qué otra cosa es una instancia?
Los varargs son solo azúcar sintáctica para crear y pasar matrices. Ya que definiste tu método como
public static void foo(Object... bar)
Java crea una matriz Object[]
si usted llama al método como foo(1,2,3)
o foo(new Integer(1), new Integer(2), new Integer(3))
.
Sin embargo, también puede pasar su propia matriz a un método que requiere un parámetro varargs. En este caso, Java no crea una nueva matriz para usted, solo pasa la matriz que creó. En las dos últimas llamadas, creas explícitamente una matriz Integer[]
.
Según la especificación del lenguaje Java :
el resultado del operador instanceof es verdadero si el valor de la RelationalExpression no es nulo y la referencia se podría convertir (§15.16) al ReferenceType sin generar una excepción ClassCastException.
En su caso, el parámetro Object[]
no se puede convertir en un Integer[]
por lo que devuelve falso.
el caso en el que la barra no es una matriz de enteros es porque es una matriz de Objeto como se especificó en su firma de método foo
: Object... args
es azúcar sintáctica para Object[] args
y al resolver este método, el compilador creará una matriz de objetos.
Para tener siempre una matriz de Integer, puede cambiar la firma del método foo(Integer... args)
a foo(Integer... args)
-
foo(1,2,3);
Éste coloca automáticamente los números 1
, 2
y 3
a los Integer
y, dado que son subtipos de Object[]
se crea una matriz de Object[]
, que consta de tres Integer
s. Un Object[]
matriz Object[]
no es Integer[]
y es por eso que obtienes false
.
-
foo(new Integer(1), new Integer(2), new Integer(3));
Aquí, no se aplica el boxeo automático, pero al final tendrá nuevamente un Object[]
matriz Object[]
que consta de tres Integer
s. Nuevamente, el Object[]
no es un Integer[]
y es por eso que obtienes false
.
-
foo(new Integer[]{1,2,3});
Aquí solo tiene un argumento, a diferencia de los dos casos anteriores, en el que tenía tres envueltos en una matriz. Por lo tanto, teniendo solo un argumento Integer[]
, en Runtime la bar instanceof Integer[]
comparación de bar instanceof Integer[]
devolverá true
, porque los enteros es lo que realmente tiene.
-
foo(new Integer[] {new Integer(1), new Integer(2), new Integer(3)});
Igual que el anterior: en Runtime, verificará si el conjunto Integer[]
proporcionado Integer[]
es un conjunto de Integer
s, que es true
.