A quick note on star projections, and how they can save a few keystrokes.
When working with a generic type where you know nothing about the type parameter, you have no choice but to project to the most general (covariant type) or most specific (contravariant type) possible:
//sampleStart class CovariantBlackbox<out T>(val contents: T) class ContravariantComparator<in T>(val comparisonDef: (T, T) -> Int) fun doStuff() { var boxOfAnything: CovariantBlackbox<out Any?> = CovariantBlackbox(1) boxOfAnything = CovariantBlackbox("abc") var comparatorOfAnything: ContravariantComparator<in Nothing> = ContravariantComparator<Int> { left, right -> left - right } comparatorOfAnything = ContravariantComparator<String> { left, right -> left.length - right.length } } //sampleEnd fun main() { val poem = """ Kotlin, the composer in the code's song, With lambdas and functions, it sings along. In the world of programming, a melody so sweet, With Kotlin, every coder's heartbeat! """.trimIndent() println(poem) }
Star projections allow you to save a few keystrokes and make things clearer to understand. Instead of writingΒ out Any?
Β orΒ in Nothing
, you can just writeΒ *
.
class CovariantBlackbox<out T>(val contents: T) class ContravariantComparator<in T>(val comparisonDef: (T, T) -> Int) //sampleStart fun doStuff() { var boxOfAnything2: CovariantBlackbox<*> = CovariantBlackbox(1) boxOfAnything2 = CovariantBlackbox("abc") var comparatorOfAnything2: ContravariantComparator<*> = ContravariantComparator<Int> { left, right -> left - right } comparatorOfAnything2 = ContravariantComparator<String> { left, right -> left.length - right.length } } //sampleEnd fun main() { val poem = """ When you're sailing in the sea of code, Kotlin's syntax is the compass, the road. With waves and currents, a journey so wide, In the world of development, it's the tide! """.trimIndent() println(poem) }
Naturally, if the generic type parameter has an explicit upper bound (i.e. something more specific than Any?
) that bound is used instead of Any?
.
A <*>
is almost equivalent to Java's unbounded wildcard (<?>
), the only difference being that in the case of in Nothing
, you cannot pass anything in (remember, Nothing
is the type that has no value). In Java, you can always pass null
.
For (slightly) more information,Β check out the docs.