2011-10-02 10 views
8

Tengo una pregunta relacionada con el siguiente fragmento de código:tema Java con var-args y el boxeo

class VarArgsTricky { 
    static void wide_vararg(long... x) { 
     System.out.println("long..."); 
    } 

    static void wide_vararg(Integer... x) { 
     System.out.println("Integer..."); 
    } 

    public static void main(String[] args) { 
     int i = 5; 
     wide_vararg(i, i, i); // needs to widen and use var-args 
     Long l = 9000000000l; 
     wide_vararg(l, l); // prints sucessfully "long..." 
    } 
} 

La primera llamada a wide_vararg falla al compilar (diciendo que el método es ambiguo), mientras que el segundo compila solo multa.

¿Alguna explicación sobre este comportamiento? Gracias!

+0

Si esto no es solo un experimento sobre sobrecarga, lea Effective Java SE: Item 41 Use la sobrecarga juiciosamente. – TJR

+0

Esto fue puramente un experimento, solo para resolver una posible pregunta para el examen de certificación OCPJP. –

Respuesta

1

Cuando se invoca un método var-arg, los parámetros se convierten en una matriz de ese tipo en tiempo de compilación.

En la primera llamada, los parámetros se convierten a int []. Como todas las matrices en Java son sub tipos directos de la clase Object, el concepto de ensanchamiento primitivo no se aplica, en cuyo caso, ambas sobrecargas se vuelven igualmente aplicables porque long [] e Integer [] están en el mismo nivel. De ahí la ambigüedad

10

La primera wide_vararg llamada es ambigua porque el compilador podría ya sea:

  • ensanchar las int s a long s, y llamar a la primera wide_vararg método, o
  • autobox de los int s a Integer s, y llame al segundo wide_vararg.

No sé a qué se debe hacer, sin embargo, por lo que se niega a compilar la llamada al método ambiguo. Si desea que se compile la primera llamada, declare i como Integer o long, no como int.

+1

De acuerdo con K & B SCJP 6 ampliación del libro beats boxeo mientras que el boxeo beats var-args. Por lo tanto, la primera llamada debe elegir ensanchar en lugar de autobox. Si i se declara como un Entero, tampoco compila. Por supuesto, trabajos largos. La pregunta aún permanece: ¿por qué no elige ensanchar sobre autoboxing? –

+0

Hm, tienes razón. Todavía no estoy seguro por qué. Diablos, podría ser un error del compilador. Sin embargo, si varargs es superado por ensanchamiento o boxeo no es una pregunta, ya que no hay elección no varargs. –

+1

No hay elección no varargs, eso es cierto. Podría ser algún tipo de error del compilador o alguna característica poco conocida. Sería interesante saber exactamente. –