Alguien es capaz de predecir la ejecucion del siguiente codigo que usa var args?
public class TestAbsurdo {
TestAbsurdo(Integer... wis) {
System.out.println("Constructor Var Args con Integer wrapper.");
}
TestAbsurdo(int i, int j) {
System.out.println("Constructor con dos argumentos int.");
}
TestAbsurdo(Integer wi, Integer wj) {
System.out.println("Constructor con dos argumentos Integer wrapper.");
}
public static void main(String... args) {
System.out.println("Llamamos a TestAbsurdo(2,3)");
new TestAbsurdo(2, 3);
System.out.println("Llamamos a TestAbsurdo(new Integer(2),new Integer(3))");
new TestAbsurdo(new Integer(2), new Integer(3));
}
}
Bien, la buena noticia es que de todos los comportamientos posibles, el que parece mas razonable a priori, es realmente el que se da.
Basicamente, de todas las versiones del constructor TestAbsurdo, se usa la que sea mas especifico para la llamada.
Llamamos a TestAbsurdo(2,3)
Version con dos argumentos int.
Llamamos a TestAbsurdo(new Integer(2),new Integer(3))
Version con dos argumentos Integer wrapper.
Por si alguien se lo pregunta, lo siguiente no compila:
new TestAbsurdo(new Integer(2), 3);
The constructor TestAbsurdo(Integer[]) is ambiguous
Si, sinembargo comentamos las definiciones especificas y dejamos unicamente el constructor con var args:
public class TestAbsurdo {
TestAbsurdo(Integer... wis) {
System.out.println("Version Var Args con Integer wrapper.");
}
public static void main(String... args) {
System.out.println("Llamamos a TestAbsurdo(2,3)");
new TestAbsurdo(2, 3);
System.out.println("Llamamos a TestAbsurdo(new Integer(2),new Integer(3))");
new TestAbsurdo(new Integer(2), new Integer(3));
}
}
El resultado que tenemos es:
Llamamos a TestAbsurdo(2,3)
Version Var Args con Integer wrapper.
Llamamos a TestAbsurdo(new Integer(2),new Integer(3))
Version Var Args con Integer wrapper.
Moraleja: Los var args dan mucha flexibilidad a las APIs, pero, los mismos chicos de Sun, desaconsejan su uso en la sobrecarga de metodos, para evitar este tipo de situaciones, que puede tener desagradables consecuencias.
Por cierto, quizas a alguno le ha llamado la atencion el uso de:
public static void main(String... args)
En lugar del clasico:
public static void main(String[] args)
Ninguna razon especial, ambos son perfectamente validos e intercambiables a partir de Java5. La unica razon por la que he usado la forma var args, es que la primera me parecia mas adecuada en un articulo sobre var args.