Star Projection
In this page:
Using Star Projection in Type Checks
Because generic type arguments are erased at runtime, checking whether something is a List of unknown element type uses the star projection syntax List<*>.
Example: Using Star Projection in Type Checks
fun printSize(value: Any) {
if (value is List<*>) {
println("List size: ${value.size}")
}
}
fun main() {
printSize(listOf(1, 2, 3))
printSize(listOf("a", "b"))
}
Login to try C/C++/Java/PHP code in the editor
Reading from a Star-Projected Type
A star-projected generic type still allows reading elements out safely, since any element can always be treated as Any? regardless of its real type.
Example: Reading from a Star-Projected Type
fun printAll(items: List<*>) {
for (item in items) {
println(item)
}
}
fun main() {
printAll(listOf(1, "two", 3.0))
}
Login to try C/C++/Java/PHP code in the editor
Why Writing Is Disallowed
You cannot add elements to a star-projected MutableList<*> because the compiler has no way to guarantee that whatever you try to insert matches the list's real, unknown element type.
Example: Why Writing Is Disallowed
fun describeMutable(list: MutableList<*>) {
// list.add("something") would not compile here
println("A mutable list with ${list.size} elements of an unknown type")
}
fun main() {
val numbers = mutableListOf(1, 2, 3)
describeMutable(numbers)
}
Login to try C/C++/Java/PHP code in the editor
Star Projection vs a Concrete Type
Whenever the actual element type is known and relevant, prefer a concrete generic type like List<String> over List<*>, since it lets the compiler check far more of your code for correctness.
Example: Star Projection vs a Concrete Type
fun sumConcrete(numbers: List<Int>): Int = numbers.sum()
fun main() {
println(sumConcrete(listOf(1, 2, 3, 4)))
}
Login to try C/C++/Java/PHP code in the editor
- Trying to add an element to a
MutableList<*>, which the compiler rejects since the actual element type is unknown, so nothing can be safely inserted. - Confusing
List<*>withList<Any?>; a star projection is more restrictive because it also blocks unsafe writes, whileList<Any?>allows adding any value. - Overusing star projection when the actual type parameter is already known and a concrete generic type would be clearer and safer.
Type<*>(a star projection) represents a generic type when the exact type argument is unknown or unimportant.- A star-projected generic type allows safe reading (of a supertype like
Any?) but disallows writing, since the compiler cannot verify type safety for insertion. - Star projection is commonly used in
ischecks, likeis List<*>, since erasure prevents checking the actual element type. List<*>behaves like a read-only list of unknown element type, distinct fromList<Any?>which explicitly allows any type.
Chapter Quiz — Complete all 6 topics to unlock
0/6 topics done
Complete these topics first: