es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Por qué el borrado de tipos genéricos impide la anulación en este caso?

El código a continuación no se compila en OpenjDK 11.
Me parece que el método test1 en B debería reemplazar al método test1 en A, porque:

  1. Los métodos tienen el mismo nombre.
  2. Los métodos tienen la misma lista de parámetros.
  3. Los métodos tienen la misma visibilidad.
  4. Los métodos en realidad no lanzan excepciones comprobadas potencialmente incompatibles.
  5. Sus tipos de retorno son covariantes.

Tomé un decompilador y descompilé cada clase por separado. El código compilado realmente funcionó como yo esperaba. Reemplazó U extends Number con Number, T extends Integer con Integer, y así sucesivamente. Pero cuando intento compilar las dos clases juntas, obtengo un error en la segunda clase que dice que el test en la segunda clase no reemplaza a un método en la primera clase.

Estoy perdiendo algo grande o pequeño aquí. Y probablemente esté relacionado con el punto 5. Tal vez los tipos no sean covariantes. ¿Puedes ayudarme?

“`
class A {
<u extends="" number,="" t="" extends="" number=""> U test(T test) {
System.out.println("En A.test(T test)");
return null;
}
//El decompilador muestra que el método anterior se transforma en
//Number test(Number test)
//Al igual que el método de abajo.

<pre><code>Number test2(Number test) {
return null;
}
</code></pre>

}

class B extends A {
//Sobrescritura fallida. Error del compilador.
@Override
<u extends="" integer,="" t="" extends="" number=""> U test(T test) {
System.out.println("En B.test(T test)");
return null;
}
//El decompilador muestra que el método anterior se transforma en
//Integer test(Number test)
//Al igual que el método de abajo.

<pre><code>//Sobrescritura exitosa
@Override
Integer test2(Number test) {
return null;
}
</code></pre>

}
“`

Tags:  , ,

Answer

  1. Avatar for davy.ai

    El código no se compila en OpenJDK 11 porque los tipos genéricos utilizados en la firma del método test() en la clase B no son covariantes con los tipos utilizados en la firma del método test() en la clase A. Covariancia se refiere a una relación entre tipos donde un subtipo puede ser utilizado en lugar de su supertipo. En este caso, los tipos genéricos utilizados en la clase B no son subtipos de los tipos genéricos utilizados en la clase A.

    Para solucionar el problema, necesitas utilizar los mismos tipos genéricos en ambas firmas de los métodos test(). Por ejemplo, podrías cambiar la firma del método test() en la clase B a:

    <t extends="" number=""> Integer test(T test)

    Esto haría que el tipo genérico utilizado en la clase B sea un subtipo del tipo genérico utilizado en la clase A, permitiendo una sobrescritura exitosa del método.

Comments are closed.