Hoy me encontré con algo interesante. Supongamos la siguiente clase de Java 6:Reemplazando un método que usa borrado de tipo
public class Ereasure {
public Object get(Object o) {
return null; // dummy
}
public static class Derived<T> extends Ereasure{
// (1)
@Override
public Object get(T o) {
return super.get(o);
}
// (2)
/*
@Override
public Object get(Object o) {
return super.get(o);
}*/
}
}
Si intenta compilar el ejemplo anterior, el compilador dice Ereasure.java:9: método no anula ni poner en práctica un método de un supertipo @ Override Si quita la anotación @Override (que no debería ser necesaria), dice Ereasure.java:8: name clash: get (T) en Ereasure.Derived y get (java.lang.Object) en Ereasure tiene la misma eliminación , sin embargo, ninguno reemplaza al otro Esto es un poco contradictorio, ya que T debe entrar en Object y, por lo tanto, anular el método get de las clases padre.
Si deja (1) no anotados y descomenta (2) (1) sobrecargas (2) tampoco funcionaría. salida del compilador:
Ereasure.java:15: get(T) is already defined in Ereasure.Derived
public Object get(Object o) {
Como conclusión, T está siendo ereased al objeto, pero no puede anular el padre método GET.
Mi pregunta es ahora, ¿por qué no compila al menos uno de los ejemplos?
@ toto2 Creo que es cierto, pero también creo que es un caso de esquina aparentemente indocumentado interesante. De acuerdo con las notas del compilador solar en Type Erasure, la definición del método en Derived debe convertir el tipo ilimitado en Obtiene get to public Object get (Objeto o) que, dado que es una subscripción del padre, debe anularse. Creo que tiene razón en que no hay forma de convertir esta cosa en bytecode para resolver la ambigüedad del envío de métodos resultante del tipo ilimitado. – nsfyn55