In Java, suppose we have a generic interface called GenericClass that does not have any methods that take T as arguments, but returns values of type T:Then, storing a reference to a GenericClass instance in a variable of type GenericClass is extremely safe — there are no consumer-methods to call. But Java still forbids this:

To do this, we must declare the object of type GenericClass<? Extends Object >,But this makes no sense, because we can call all the same methods on this object as before, so the more complex types don’t add value.

In Kotlin, the out modifier is provided to explain this to the compiler. We can annotate the GenericClass type parameter T to ensure that it is only returned (produced) from the GenericClass member and never consumed.

The general principles are: When the type parameter T of a GenericClass is declared out, it can only appear in the output-position of a GenericClass member, but the return is GenericClass (as in GenericClass), Can safely be used as a superclass of GenericClass (GenericClass in this article).

In short, they say that the GenericClass is covariant on the parameter T, or that T is a covariant type parameter. You can think of GenericClass as a producer of T, not a consumer of T.

The out and in modifiers are called type-variant annotations. In inverts a type parameter: it can only be consumed, not produced.

A good example of an inverter type is Comparable:

A collection of covariance

In Kotlin, a non-null type is a subtype of a nullable type.

Covariant Java implementations

List<? extends Number> list = new ArrayList<Integer>();
Copy the code

Covariant implemented by Kotlin

val list: MutableList<out Number> = arrayListOf<Int>()
Copy the code

A collection of inverter

Java implementation of inverse

List<? super Integer> list = new ArrayList<Number>();
Copy the code

The corresponding Kotlin inverse implementation:

val list: MutableList<in Int> = arrayListOf<Number>()
Copy the code

Conclusion:

Variants (covariant and contravariant) involve set elements, set classes. Covariant says that the elements of two sets are subclass relations, and these two sets are subclass relations, and with subclass relations, you can represent them in terms of polymorphism. The contravariant relationship is the other way around, contravariant means that the elements of two sets are superclass, but the two sets can be subclass.

Use Kotlin to efficiently develop Android, common tool classes such as SharePreferenceUtil encapsulation, and control extensions github.com/AlbertShen0… Welcome Star, take it with you.