Var args de Java5 en la construccion de APIs

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.