¿Se pueden evitar las advertencias no verificadas al anular un método con parámetros de tipo sin formato?

StackOverflow https://stackoverflow.com/questions/241539

Pregunta

Estoy extendiendo una clase definida en una biblioteca que no puedo cambiar:

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

Si estoy definiendo una clase 'Child' que amplía Parent y estoy usando Java 6 con genéricos, ¿cuál es la mejor manera de anular el método init sin recibir advertencias no controladas?

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 agrego parámetros genéricos, obtengo:

   // 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 se produce independientemente de si uso un tipo específico, un comodín limitado o un comodín ilimitado. ¿Existe una forma correcta o idiomática de anular un método no genérico sin advertencias y sin usar @SuppressWarnings (& Quot; sin marcar & Quot;)?

¿Fue útil?

Solución

Sí, debe declarar el método de anulación con la misma firma que en la clase principal, sin agregar ninguna información genérica.

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

Otros consejos

Respuesta corta: no hay forma de hacerlo.

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

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

El problema es que, a pesar de que después del borrado del tipo, ambos init () tienen la misma firma, de hecho pueden ser métodos diferentes, o el mismo (*). El compilador no puede determinar si anula o sobrecarga, por lo que está prohibido.

(*) Supongamos que el desarrollador de la biblioteca quiere decir init (Map & Lt; String, Integer & Gt;). Ahora está implementando init (Map & Lt; String, String & Gt;). Esto es una sobrecarga, y deberían existir dos métodos en la clase vtable de Child.

Pero, ¿qué pasa si el desarrollador de la biblioteca quiere decir init (Map < String, String >)? Entonces se anula, y su método debería reemplazar init original en la clase Child, y solo habría un método en la vtable de Child.

P.S. Odio cómo se implementaron los genéricos en Java :-(

Creo que la respuesta anterior significaba @SuppressWarnings (" rawtypes ") en su lugar.

Debe declarar el método con la misma firma que el padre y, por lo tanto, recibirá advertencias cuando compile. Puede suprimirlos con @SuppressWarnings (& Quot; sin marcar & Quot;)

La razón por la cual 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 permitirlo. Como está heredando de una clase no genérica, siempre será posible crear una Colección con contenido no válido.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top