Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Wildcard-types vs Kotlin Star-projection

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<*> 
like image 916
pokemzok Avatar asked Aug 05 '17 09:08

pokemzok


People also ask

What is star projection in Kotlin?

Star Projection: Sometimes you want to say that you know nothing about the type argument, but still want to use it in a safe way. The safe way here is to define such a projection of the generic type, that every concrete instantiation of that generic type would be a subtype of that projection.

What is the difference between * and any in Kotlin generics?

When we define a collection with "*", it should contain the object of only that type. There should not be any mix and match between the data types inside a collection. If we use "Any", we can mix and match the data types, which means we can have multiple data types in a collection.

What is wildcard types in Java?

Wildcards in Java are basically the question marks which we use in generic programming, it basically represents the unknown type. We use Java Wildcard widely in situations such as in a type of parameter, local variable, or field and also as a return type.

Can wildcard types be replaced by any type?

Due to extensive capture conversion, in most places, compiler treats wildcards as if they are type variables. Therefore indeed programmer can replace wildcard with type variables in such places, a sort of manual capture conversion.

What is a star projection in Kotlin?

Note: In Kotlin 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). in Java and Kotlin.

What are the different types of wildcards in Java?

? extends T — Wildcard with an upper bound T meaning: Only types that are subtypes of T are all allowed ? super T — Wildcard with a lower bound meaning: Only types that are supertypes of T are allowed only I hope Java wildcards are pretty much clear to you. Invariant — Where two objects are not equal. This might not be clear with just a definition.

Is Kotlin faster than Java?

One way in which Kotlin can be faster than Java is inline functions. With inline functions, code using higher-order functions such as filter or map can be compiled to simple loop-based bytecode that doesn't create any objects or use any virtual calls (unlike Java code that uses the same type of functions).

What is declaration-site variance in Kotlin?

In Kotlin, There’s a solution for the same, which is declaration-site variance. In which we annotate the type parameter of the Class/Interface to make sure that the object is only returned and not consumed. This is done by defining the type as out (variance annotation).


1 Answers

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).

like image 181
hotkey Avatar answered Sep 27 '22 17:09

hotkey