I am reading and trying to understand Kotlin type projections, sometimes I come up with confusing things like this:
For contravariant type parameters such as
Consumer<in T>, a star projection is equivalent to<in Nothing>. In effect, you can’t call any methods that haveTin the signature on such a star projection. If the type parameter is contravariant, it acts only as a consumer, and, as we discussed earlier, you don’t know exactly what it can consume. Therefore, you can’t give it anything to consume.You can use the star projection syntax when the information about type arguments isn’t important: you don’t use any methods that refer to the type parameter in the signature, or you only read the data and you don’t care about its specific type. For instance, you can implement the
printFirstfunction takingList<*>as a parameter.
What does it mean to contravariant type to have a star projection and how does it come up to
This is also explained in the Kotlin documentation:
Example
We have a class
Foo<T>with contravariantT(declaration-site), i.e.Fooonly works as a consumer ofT:We can use this type in simple generic functions as follows:
(used
Fin order to distinguish from class type parameterT)This works fine since we use
Fooas intended: As a consumer ofTs.Now, your quote simply says that having a parameter of type
con: Foo<*>instead ofcon: Foo<T>would have the following effect: "you can't call any methods that haveTin the signature".Thus, the following fails:
It's not safe to call
acceptwith an instance ofFbecause we don't know the type ofFoo(denoted by star projection).