Kotlin Star Projections
A star projection writes List<*> when a program needs a list but does not know or does not care about its element type. The list still gives up its size, and each element it hands back is typed Any?.
One pair of functions for every list
printSize and printFirst both take List<*>. The same two functions serve a list of strings and a list of ints.
fun printSize(list: List<*>) {
println(list.size)
}
fun printFirst(list: List<*>) {
println(list[0])
}
fun main() {
val words = listOf("alpha", "beta", "gamma")
val numbers = listOf(7, 8, 9)
printSize(words)
printFirst(words)
printSize(numbers)
printFirst(numbers)
}A mutable star list still shrinks
shrink receives a MutableList<*>. Adding any element is refused, since its type is unknown, but removal by index and size checks still work.
fun shrink(list: MutableList<*>) {
list.removeAt(0)
println(list.size)
}
fun main() {
val items = mutableListOf<Any?>("pen", 4, "cup")
shrink(items)
println(items.size)
}A star element reads as Any?
The element pulled from a List<*> lands in a variable typed Any?. Printing that variable is safe and needs no cast.
fun main() {
val mixed: List<*> = listOf("kite", 12, true)
val first: Any? = mixed[0]
println(first)
println(mixed.size)
}Example
fun describe(list: List<*>) {
println("size " + list.size)
val first: Any? = list.firstOrNull()
println(first)
}
fun main() {
describe(listOf("red", "green"))
describe(listOf(100, 200, 300))
val bag: MutableList<*> = mutableListOf<Any?>(1, 2, 3)
bag.removeAt(0)
describe(bag)
}Key points
- The star in List<*> stands in for an unknown element type.
- A function can take List<*> and serve lists of any element type.
- Size and position checks work the same on a star projected list.
- Reading an element from List<*> gives Any?, the safe common type.
- Writing through a MutableList<*> is closed off, since no value can be proven to fit the unknown element type.
In this example, describe accepts a List<*> and prints its size and first element. It serves a string list, an int list, and a mutable list that lost its first element through the star view. The first element is held as Any? each time, so no cast appears anywhere.
Note
A star projection trades element detail for flexibility, so it fits code that only inspects a collection.
Try it Yourself
Edit the code, then press Run.
Running is simulated · Kotlin Playground
Exercise
What type does reading an element from a List<*> give?