2008-10-27 9 views
14

les extiendo una clase definida en una biblioteca que no puedo cambiar:¿Se pueden evitar las advertencias no controladas al anular un método con parámetros de tipo sin formato?

public class Parent 
{ 
    public void init(Map properties) { ... } 
} 

Si estoy definiendo una clase de 'niño' que se extiende de Padres y estoy usando Java 6 con los genéricos, ¿cuál es la mejor manera de anular el método init sin obtener advertencias sin marcar?

public class Child extends Parent 
{ 
    // warning: Map is a raw type. References to generic type Map<K,V> should be parameterized 
    public void init(Map properties) { } 
} 

Si añado parámetros genéricos, me sale: se produce

// error: The method init(Map<Object,Object>) of type Child has the same erasure as init(Map) of type Parent but does not override it 
    public void init(Map<Object,Object>) { ... } 
    // same error 
    public void init(Map<? extends Object,? extends Object>) { ... } 
    // same error 
    public void init(Map<?,?>) { ... } 

Este error independientemente de si utilizo un tipo específico, un comodín acotada, o un comodín sin límites. ¿Existe una forma correcta o idiomática de anular un método no genérico sin advertencias y sin usar @SuppressWarnings ("desmarcado")?

Respuesta

12

Sí, usted tiene que declarar el método predominante con la misma firma como en la clase padre, sin añadir ninguna información genéricos.

Creo que su mejor apuesta es agregue la anotación @SuppressWarnings("unchecked") al parámetro de tipo sin formato, no el método, por lo que no silenciará otras advertencias genéricas que pueda tener en su propio código.

+0

@SuppressWarnings es definitivamente su mejor apuesta aquí. Apesta, pero eso es lo que sucede cuando intentas forzar genéricos a una biblioteca que no los usa. –

+0

'@SuppressWarnings (" rawtypes ")' también debería ser suficiente. –

2

Respuesta corta: no hay manera de hacerlo.

Respuesta insatisfactoria: desactive las advertencias (específicas) en su IDE/build.xml.

Si no puede cambiar la biblioteca, por desgracia, debe seguir los métodos no genéricos.

El problema es que, a pesar del tipo de borrado, tanto init() tienen la misma firma, que de hecho pueden ser métodos diferentes, o lo mismo (*). El compilador no puede decir si debe anular o sobrecargar, por lo que está prohibido.

(*) Supongamos que el desarrollador de la biblioteca significaba init (Map < String, Integer >). Ahora está implementando init (Map < String, String >). Esto es una sobrecarga y deben existir dos métodos en el vtable de la clase Child.

¿Pero y si el desarrollador de la biblioteca significaba init (Map < String, String >)? Entonces está anulando, y su método debería reemplazar init original en la clase Child, y solo habría un método en el vtable de Child.

P.S. No me gusta lo Genéricos implementados en Java :-(

+0

¿Puede explicar por qué los métodos con la misma firma (borrada) pueden ser métodos diferentes para el compilador? El compilador no sabe lo que el desarrollador _meant_ al codificar ... ;-) – nrainer

0

Debe declarar el método con la misma firma que el elemento primario, y por lo tanto, recibirá advertencias cuando compile. Puede suprimirlas con @SuppressWarnings ("desmarcada")

La razón por la que no hay forma de deshacerse de esto es que las advertencias están ahí para hacerle saber que es posible crear colecciones con tipos no válidos en ellas. Las advertencias solo deberían desaparecer cuando se haya eliminado todo el código que podría permitir eso. Como hereda de una clase no genérica, siempre será posible crear una Colección con contenido no válido.

2

Creo que la respuesta anterior significa decir @SuppressWarnings ("tipos de raw") en su lugar.

Cuestiones relacionadas