Kotlin 2.4 Collection Literals and Type Inference

Kotlin 2.4 introduces experimental support for collection literals, allowing collections to be created using square brackets.
Experimental Support for collection literals
Support for collection literals Kotlin 2.4.0 introduces experimental support for collection literals. You can now create collections in a simpler and more concise way using brackets [].
https://kotlinlang.org/docs/whatsnew24.html#support-for-collection-literals
kotlin {
jvmToolchain(21)
compilerOptions {
freeCompilerArgs.add("-Xcollection-literals")
}
}
Let’s compare the inferred types of several common collection APIs.
val names = mutableListOf("Joe", "Alice")
// MutableList<String>
val names = listOf("Joe", "Alice")
// List<String>
val names = listOf("Joe", "Alice").toMutableList()
// MutableList<String>
val names = arrayOf("Joe", "Alice")
// Array<String>
With collection literals enabled:
val names = ["Joe", "Alice"]
// Array<String>
Without an expected type, the compiler infers Array<String>.
However, collection literals are context-sensitive:
val names: MutableList<String> = ["Joe", "Alice"]
// MutableList<String>
The same literal now becomes a MutableList<String> because the target type is explicitly declared.
Summary
| Expression | Inferred Type |
|---|---|
mutableListOf("Joe", "Alice") |
MutableList<String> |
listOf("Joe", "Alice") |
List<String> |
listOf("Joe", "Alice").toMutableList() |
MutableList<String> |
arrayOf("Joe", "Alice") |
Array<String> |
["Joe", "Alice"] |
Array<String> |
val names: MutableList<String> = ["Joe", "Alice"] |
MutableList<String> |
The interesting part is that collection literals do not always represent a single concrete collection type. The compiler uses the surrounding context to determine the final type.