2012-01-12 30 views
13

Me preguntaba por qué no está permitido en Java sobrecargar Foo(Object[] args) con Foo(Object... args), aunque se usan de otra manera?¿Por qué no se permite en Java sobrecargar Foo (Objeto ...) con Foo (Objeto [])?

Foo(Object[] args){} 

se utiliza como:

Foo(new Object[]{new Object(), new Object()}); 

mientras que la otra forma:

Foo(Object... args){} 

se utiliza como:

Foo(new Object(), new Object()); 

¿Hay alguna razón detrás de esto?

+0

pregunta interesante +1 – mKorbel

+1

Me puede estar faltando algo, pero ¿por qué necesita una sobrecarga? Si declara su método como 'void foo (Object ... args)', puede llamarlo con ** ** ** foo (nuevo Object(), new Object()) '** o **' foo (nuevo Objeto [] {nuevo Objeto(), nuevo Objeto()}) 'y obtiene el mismo resultado. Consulte [esta pregunta relacionada] (http://stackoverflow.com/questions/1656901/varargs-and-the-argument) para ver un ejemplo. –

+0

the vararg es solo un indicador de la firma del método que transmuta la última matriz declarada (como 'int []' o 'Object []') a vararg type. Aparte de eso, no hay diferencia entre las firmas de método. La misma pregunta sería como no se puede sobrecargar el método 'privado' y' público'. – bestsss

Respuesta

25

Esto 15.12.2.5 Choosing the Most Specific Method habla de esto, pero es bastante complejo. p.ej. Elegir entre Foo (Números ...) y Foo (Números enteros)

En aras de la compatibilidad con versiones anteriores, estas son en realidad la misma cosa.

public Foo(Object... args){} // syntactic sugar for Foo(Object[] args){} 

// calls the varargs method. 
Foo(new Object[]{new Object(), new Object()}); 

e.g. puede definir main() como

public static void main(String... args) { 

Una manera de hacer que los diferencia es tomar un argumento ante los varargs

public Foo(Object o, Object... os){} 

public Foo(Object[] os) {} 

Foo(new Object(), new Object()); // calls the first. 

Foo(new Object[]{new Object(), new Object()}); // calls the second. 

Ellos no son exactamente lo mismo. La diferencia sutil es que, aunque puede pasar una matriz a una varargs, no puede tratar un parámetro de matriz como varargs.

public Foo(Object... os){} 

public Bar(Object[] os) {} 

Foo(new Object[]{new Object(), new Object()}); // compiles fine. 

Bar(new Object(), new Object()); // Fails to compile. 

Además, un varags debe ser el último parámetro.

public Foo(Object... os, int i){} // fails to compile. 

public Bar(Object[] os, int i) {} // compiles ok. 
+0

+1 buena explicación. ¿Hay alguna especificación de idioma escrita para esto? –

+0

:-) buena respuesta +1 – mKorbel

+0

Eche un vistazo a [esta pregunta] (http://stackoverflow.com/q/14937948/597657) por favor. –

3

La respuesta más directa a la pregunta es que tener ambas declaraciones crearía una ambigüedad en la lógica de búsqueda de métodos. Si ambos declarados en la misma clase, no habría manera de averiguar qué método que quería cuando se llama así:

Object[] a = new Object[10]; 
Foo(a); // array or vararg? 

y Java requiere que haya siempre un método más específico para cada invocación de método. Para por qué, vea la respuesta de Peter.

+0

son * exactamente * lo mismo, no ambigüedad, simplemente no pueden existir en la misma clase – bestsss

Cuestiones relacionadas