Java Wildcard-types vs Kotlin Star-projection

2020-02-26 08:08发布

问题:

I was reading a kotlin documentation about differences between Java and Kotlin here https://kotlinlang.org/docs/reference/comparison-to-java.html. It was stated there that Kotlin does not have wildcard-types. However after reading carefully through the documentation of generics I have found information about star-projection and honestly I can't see the difference. Can somebody explain to me how this

List<?> list;

differs from this

lateinit var list: MutableList<*> 

回答1:

Probably what it means is that Kotlin doesn't have wildcards in the same form as they are present in Java. Instead, Kotlin uses a different concept of mixed-site variance, which adds an option to specify the variance at declaration-site, that is something you cannot do with Java wildcards.

As to the star-projection, it is actually almost equivalent to an unbounded Java wildcard. However, there is at least one difference related to the Kotlin type system.

When you have a List<?>, the type is unknown to Java, but all Java referential types are nullable, and therefore you can safely pass a null as an argument of the unknown type, e.g. list.add(null).

In Kotlin that is not true, a star projection MutableList<*> combines both out Any? and in Nothing projections, and the latter means that you cannot pass anything at all to the methods where the type is unknown (Nothing is the type that has no value).

The same can be said of the out-projections: while you can pass a null as a Java bounded wildcard type ? extends T, you cannot do the same with Kotlin out T projection.

And the exact equivalent of the Java unbounded wildcard is <in Nothing?>, because it lets you pass a null as an argument of the unknown type (Nothing? is Nothing ∪ { null }, this is the type that has only null value).