
Tipos
Java es un lenguaje de tipado estático, lo que significa que primero debe declarar una variable y su tipo antes de usarla.
Por ejemplo: int myInteger = 42;
Ingrese tipos genéricos.
Tipos genéricos
Definición: "Un tipo genérico es una clase o interfaz genérica que se parametriza sobre tipos".
Esencialmente, los tipos genéricos le permiten escribir una clase (o método) genérico general que funciona con diferentes tipos, lo que permite la reutilización del código.
En lugar de especificar obj
que sea de un int
tipo, o un String
tipo, o cualquier otro tipo, define la Box
clase para aceptar un parámetro de tipo <
; T>. Luego, puede n
usar T para representar ese tipo genérico en cualquier parte de su clase.
Ahora, ingrese covarianza y contravarianza.
Covarianza y contravarianza
Definición
La varianza se refiere a cómo la subtipificación entre tipos más complejos se relaciona con la subtipificación entre sus componentes (fuente).
Una definición fácil de recordar (y extremadamente informal) de covarianza y contravarianza es:
- Covarianza: aceptar subtipos
- Contravarianza: aceptar supertipos
Matrices
En Java, las matrices son covariantes , lo que tiene dos implicaciones.
En primer lugar, una matriz de tipo T[]
puede contener elementos de tipo T
y sus subtipos.
Number[] nums = new Number[5];nums[0] = new Integer(1); // Oknums[1] = new Double(2.0); // Ok
En segundo lugar, una matriz de tipo S[]
es un subtipo de T[]
si S
es un subtipo de T
.
Integer[] intArr = new Integer[5];Number[] numArr = intArr; // Ok
Sin embargo, es importante recordar que: (1) numArr
es una referencia de tipo de referencia Number[]
al "objeto real" intArr
del "tipo real" Integer[]
.
Por lo tanto, la siguiente línea se compilará bien, pero producirá un tiempo de ejecución ArrayStoreException
(debido a la contaminación del montón):
numArr[0] = 1.23; // Not ok
Produce una excepción en tiempo de ejecución, porque Java sabe en tiempo de ejecución que el "objeto real" intArr
es en realidad una matriz de Integer
.
Genéricos
Con los tipos genéricos, Java no tiene forma de conocer en tiempo de ejecución la información de tipo de los parámetros de tipo, debido al borrado de tipo. Por lo tanto, no puede proteger contra la contaminación del montón en tiempo de ejecución.
Como tal, los genéricos son invariables.
ArrayList intArrList = new ArrayList();ArrayList numArrList = intArrList; // Not okArrayList anotherIntArrList = intArrList; // Ok
Los parámetros de tipo deben coincidir exactamente para proteger contra la contaminación del montón.
Pero ingrese comodines.
Comodines, covarianza y contravarianza
Con los comodines, es posible que los genéricos admitan la covarianza y la contravarianza.
Ajustando el ejemplo anterior, obtenemos esto, ¡que funciona!
ArrayList intArrList = new ArrayList();ArrayList numArrList = intArrList; // Ok
El signo de interrogación "?" se refiere a un comodín que representa un tipo desconocido. Puede tener un límite inferior, lo que restringe el tipo desconocido para que sea un tipo específico o su supertipo.
Por lo tanto, en la línea 2, se ? super Integer
traduce como “cualquier tipo que sea un tipo Integer o su supertipo”.
También puede aplicar un límite superior al comodín, que restringe el tipo desconocido a un tipo específico o su subtipo, usando ? extends Integer
.
Solo lectura y solo escritura
La covarianza y la contravarianza producen algunos resultados interesantes. Los tipos covariantes son de solo lectura, mientras que los tipos contravariantes son de solo escritura.
Recuerde que los tipos covariantes aceptan subtipos, por lo que ArrayLister> can contain any object that is either
of a
Number type or its subtype.
In this example, line 9 works, because we can be certain that whatever we get from the ArrayList can be upcasted to a
Number
type (because if it extends Number
, by definition, it is a Number
).
But
nums.add()
doesn’t work, because we cannot be sure of the “actual type” of the object. All we know is that it must be a Number
or its subtypes (e.g. Integer, Double, Long, etc.).
With contravariance, the converse is true.
Line 9 works, because we can be certain that whatever the “actual type” of the object is, it must be
Integer
or its supertype, and thus accept an Integer
object.
But line 10 doesn’t work, because we cannot be sure that we will get an
Integer
. For instance, nums
could be referencing an ArrayList of Objects
.
Applications
Therefore, since covariant types are read-only and contravariant types are write-only (loosely speaking), we can derive the following rule of thumb: “Producer extends, consumer super”.
A producer-like object that produces objects of type
T
can be of type parameter T>, while a consumer-like object that consumes objects of
type T can be of type para
meter super T>.

Original text