2008-10-06 10 views
5

considerar las siguientes firmas de método:arrays de objeto en firmas de método

public fooMethod (Foo[] foos) { /*...*/ } 

y

public fooMethod (Foo... foos) { /*...*/ } 

Explicación: El primero tiene una matriz de Foo-objetos como un argumento - fooMethod(new Foo[]{..}) - mientras que el segundo toma una cantidad arbitraria de argumentos de tipo Foo, y los presenta como una matriz de Foo: s dentro del método - fooMethod(fooObject1, fooObject2, etc...).

Java arroja un ajuste si ambos están definidos, alegando que son métodos duplicados. Hice un trabajo de detective y descubrí que la primera declaración realmente requiere una matriz explícita de objetos Foo, y esa es la única forma de llamar a ese método. La segunda forma realmente acepta tanto una cantidad arbitraria de argumentos Foo como también acepta una matriz de objetos Foo.

Entonces, la pregunta es, dado que este último método parece ser más flexible, ¿hay alguna razón para usar el primer ejemplo o me he perdido algo vital?

+0

Sin saber Java, esta es una puñalada en la oscuridad, pero supongo que la primera es marginalmente más eficiente, porque: a) es probable que solo esté pasando un solo puntero, yb) estará pasando un puntero a una porción contigua de la memoria. –

+0

@monoxide: No, ambos formularios generan bytecode de llamada equivalente, ambos formularios requieren construir una matriz para aprobar. –

+0

La segunda forma es simplemente azúcar sintáctica para el primero. Entonces, fooMethod (nuevo Foo (1), nuevo Foo (2)) es aquí idéntico a fooMethod (nuevo Foo [] {nuevo Foo (1), nuevo Foo (2)}) –

Respuesta

12

Estos métodos son en realidad lo mismo.

Esta característica se llama varargs y es una función de compilación. Detrás de las escenas se traduce a la versión anterior.

Existe un error si define un método que acepta Object ... y envió un parámetro de tipo Object []!

+0

Java le advierte sobre esto y le pide que escriba (Objeto) matriz (para el modo variadic) o (Objeto []) matriz (para el modo no variadic). :-) –

1

Este último se introdujo en Java 5 y las bibliotecas existentes se están rediseñando gradualmente para admitirlo. Aún puede usar el primero para enfatizar que el método requiere 2+ entradas, además de que existen restricciones sobre dónde ... se puede usar.

+0

Excepto que no hace hincapié en nada de eso, y de hecho, permite 0 o 1 entrada (a menos que se especifique lo contrario en la documentación, en cuyo caso la forma variadica es igual de buena). –

0

Ciertamente no hay problemas de rendimiento o cosas por considerar, por lo que todo se reduce a la semántica.

¿Espera que la persona que llama de su método tenga a mano una variedad de Foo? Luego usa la versión de Foo []. Use la variante varargs para enfatizar la posibilidad de tener un "grupo" de Foo en lugar de una matriz.

Un ejemplo clásico de varargs ist la cadena de formato (en C#, dunno cómo su llamado en Java):

string Format(string formatString, object... args) 

Aquí esperan que los argumentos para ser de diferentes tipos, por lo que tiene una serie de argumentos sería bastante inusual, de ahí la variante varargs.

Por otro lado, en algo así como

string Join(string[] substrings, char concatenationCharacter) 

utilizando una matriz es perfectamente razonable.

También tenga en cuenta que puede tener múltiples parámetros de matriz y solo un parámetro vararg al final de la lista de parámetros.

3

Me gustaría agregar a la explicación de Shimi para agregar que otra restricción de la sintaxis varargs es que el vararg debe ser el último parámetro declarado. Entonces no puede hacer esto:

void myMethod(String... values, int num); 

Esto significa que cualquier método dado solo puede tener un único parámetro vararg.En los casos en que desee pasar varias matrices, puede usar varargs para solo una de ellas.

En la práctica, los varargs están en su mejor momento cuando trata los argumentos como una cantidad arbitraria de valores distintos, en lugar de como una matriz. Java5 los asigna a una matriz simplemente porque era lo más conveniente.

Un buen ejemplo es String.format(). Aquí, los varargs se comparan con los marcadores de posición de formato en el primer argumento.

Cuestiones relacionadas