Tell me what generics are in Java and what are the differences between invariance, covariance, and contravariance when using them?
sobes.tech AI
Answer from AI
Generics in Java allow creating classes, interfaces, and methods with type parameters, ensuring type safety and code reusability without the need for casts.
Invariance means that the type parameter must exactly match. For example, List<String> is not a subtype of List<Object>.
Covariance allows using a more specific type than expected. In Java, this is implemented through wildcards with extends: List<? extends Number> — you can read elements as Number, but cannot add.
Contravariance — on the contrary, allows using a more general type. In Java, this is a wildcard with super: List<? super Integer> — you can add Integer and its subtypes, but when reading, you get Object.
Example:
List<? extends Number> numsCovariant = new ArrayList<Integer>();
Number n = numsCovariant.get(0); // reading is allowed
// numsCovariant.add(10); // compilation error
List<? super Integer> numsContravariant = new ArrayList<Number>();
numsContravariant.add(10); // adding is allowed
Object obj = numsContravariant.get(0); // reading returns Object
Thus, covariance is convenient for reading, contravariance — for writing.