2010-11-23 30 views
7

he declarado lo siguiente método:advertencia para varargs genéricos

private void mockInvokeDBHandler(Map<String, Object>... rows) { 
    List<Map<String, Object>> allRows = Arrays.asList(rows)); 
    // rest of method omitted 
} 

Se invoca por los clientes que utilizan algo así como

Map<String, Object> row1 = new HashMap<String, Object>(); 
Map<String, Object> row2 = new HashMap<String, Object>(); 

mockInvokeDBHandler(row1, row2); 

Sin embargo, la última línea se muestra más arriba genera una advertencia

Tipo de seguridad: se crea una matriz genérica de Mapa para un parámetro varargs

No entiendo completamente esto, pero supongo que es porque los parámetros varargs se convierten en matrices, y es una mala idea tener una matriz cuyo tipo es una clase genérica (porque los genéricos son invariables, mientras que los arreglos no son)

pude resolver este problema mediante el método redifining como

private void mockInvokeDBHandler(List<Map<String, Object>> rows) { 
} 

Pero esto impone la carga de poner los objetos de fila en una lista en el cliente, que prefiero evitar. ¿Hay una mejor solución?

+0

EN MIEMBRA Usted podría simplemente ignorar la advertencia. –

+0

Estoy seguro de que su código real se compila pero parece que tiene un error de publicación aquí: 'ListMap allRows', como debería ser' List > allRows' –

+0

@Mark E - gracias, el código está bien, acaba de hacer un error en mi publicación –

Respuesta

12

Para pasar los argumentos a un método varargs el compilador colocará los argumentos en una matriz.

La advertencia es para hacerle saber que el compilador no puede garantizar que cada uno de los elementos en la matriz, cada uno de los argumentos del método varags, sea realmente un Map<String, Object>.

Esto es un poco una advertencia molesta porque no hay forma de que pueda evitar esto, además de redefinir la firma del método para no usar varargs. OMI es seguro ignorarlo siempre y cuando esté seguro de los tipos de tiempo real de estos argumentos (que en este caso lo es).

4

No hay manera de evitar esta advertencia, aparte de la adición de @SuppresWarning("unchecked") al método :)

Dado que usted dice que es un método privado que no hay "clientes" en este caso y que tienes el control del método, así que ignorar la advertencia parece razonable.

Algunas veces cuando he métodos creados tomando tipos parametrizados como parámetro varargs, que he creado algunas sobrecargas:

void mockInvokeDBHandler(Map<String, Object> map1) 
void mockInvokeDBHandler(Map<String, Object> map1, Map<String, Object> map2) 
void mockInvokeDBHandler(Map<String, Object> map1, Map<String, Object> map2, Map<String, Object>... othermaps) 

que podrían evitar algunas de las advertencias, dependiendo del número de argumentos son suministrados .

+2

Evitar este tipo de sobrecarga es precisamente la razón por la que quiero usar varargs –

2

Puede reducir la carga de utilizar una lista en lugar de varargs mediante el uso de alguna interfaz de generador (por ejemplo, como the one I'm using). El uso de este CollectionBuilder, se convertiría en algo como esto:

mockInvokeDBHandler(CollectionBuilder.<Map<String, Object>>list().add(map1).add(map2).get()); 

que es más bonito sin argumentos genéricos sin embargo:

import static at.molindo.utils.collections.CollectionBuilder.list 

List<String> list = list(String.class).add("foo").addAll(set).get(); 

Ciertamente es más largo que la solución varargs, pero de todos modos bastante útil a veces.

2

Para cualquier persona que aterrice aquí, las respuestas son un poco viejas.Java 7 introdujo la anotación @Safevarargs para hacer frente a esto:

@SafeVarargs 
private void mockInvokeDBHandler(Map<String, Object>... rows) { 

Desde el javadoc:

Una afirmación programador que el cuerpo del método anotado o constructor no realizar operaciones potencialmente inseguras en sus varargs parámetro. La aplicación de esta anotación a un método o constructor suprime advertencias sin marcar sobre un no reifiable variable de aridad (vararg) tipo y suprime advertencias sin marcar sobre creación de la matriz parametrizada en llamada sitios.

Cuestiones relacionadas