Estas cosas son conocidas, en teoría tipo, como varianza, con <? extends T>
ser una notación co-variante, y <? super T>
ser una notación contra-variante. La explicación más simple es que ?
se puede reemplazar por cualquier tipo que se extienda T
en la notación co-variante, y ?
se puede reemplazar por cualquier tipo que T
se extienda en la contravariante.
El uso de contra-varianza y contradicción es mucho más difícil de lo que parece al principio, especialmente porque la varianza "alterna" dependiendo de la posición.
Un ejemplo simple sería una clase de función. Supongamos que tiene una función que toma un A
y devuelve un B
. La notación correcta para esto sería decir que A
es contravariante y B
os co-variantes.Para entender mejor cómo este es el caso, vamos a considerar un método - llamémoslo g
- que recibe esta clase hipotética función , donde se supone que f para recibir una Arc2D
y devolver una Shape
.
Dentro g
, este f
se llama el paso de una Arc2D
y el valor de retorno se utiliza para inicializar un Area
(que espera un Shape
).
Ahora, supongamos que el f
que pasa recibe Shape
y devuelve Rectangle2D
. Desde un Arc2D
es un también un Shape
, entonces g
no obtendrá un error pasar una Arc2D
a f
, y desde un Rectangle2D
es también un Shape
, entonces se puede pasar al constructor Area
's.
Si intenta invertir cualquiera de las varianzas o cambiar los tipos esperado y real en ese ejemplo, verá que falla. No tengo tiempo ahora mismo para escribir este código, y mi Java está bastante oxidada en cualquier caso, pero veré lo que puedo hacer más tarde, si nadie tiene la amabilidad de hacerlo primero.
Java efectivo es genial, pero todavía no tengo la 2da edición (( – Roman
@Roman puede descargar el capítulo sobre Genéricos del enlace que agregué :-) –
Gracias, lo leeré. ¿No es así? saber si hay otros "capítulos de muestra" disponibles de forma gratuita? – Roman