Stjärnprojektion och när * ska användas
Använd stjärnprojektion för okända generiska typer och förstå dess begränsningar.
Stjärnprojektion och när * ska användas är en gratis lektion i Kotlin Academy på CoddyKit. Detta är lektion 3 av 4. Du kan läsa vilka 3 lektioner som helst i den här lärvägen kostnadsfritt i sin helhet – därefter låser CoddyKit PRO upp alla lektioner, plus praktisk övning med en inbyggd kodredigerare och en AI-lärare dygnet runt. Den ingår i lärvägen för Kotlin Academy, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i Kotlin Academy innehåller totalt 4 lektioner.
Vad är stjärnprojektion
Stjärnprojektion (*) är Kotlins sätt att uttrycka "en generisk typ med ett okänt typargument". Det är det säkra motsvarigheten till Javas råtyp eller obegränsade wildcard <?>.
fun printList(list: List<*>) {
for (item in list) println(item)
}
fun main() {
printList(listOf(1, 2, 3))
printList(listOf("a", "b"))
printList(listOf(true, 42, "mixed"))
}Läsa från stjärnprojicerade typer
Från en List<*> kan du läsa element som Any?. Du kan inte lägga till element eftersom den faktiska typen är okänd.
fun process(list: List<*>) {
val first: Any? = list.firstOrNull()
println("First: $first, Size: ${list.size}")
// list.add("x") // compile error: can't write to List<*>
}
fun main() {
process(listOf(10, 20, 30))
}Stjärna jämfört med out Any
List<*> och List<out Any?> är likvärdiga. Stjärnprojektion är en kortform för den kovarianta projektionen med den övre gränsen.
fun sumStars(list: List<*>): Int = list.size
fun sumOut(list: List<out Any?>): Int = list.size
fun main() {
val l = listOf(1, "two", true)
println(sumStars(l)) // 3
println(sumOut(l)) // 3
}Stjärna i funktionsparametrar
Använd * i funktionssignaturer när du behöver acceptera valfri generisk variant, men bara anropa metoder som inte kräver att T är känt.
fun containerInfo(map: Map<*, *>): String {
return "keys=${map.keys.size}, values=${map.values.size}"
}
fun main() {
val m = mapOf(1 to "one", 2 to "two")
println(containerInfo(m))
}Stjärna med MutableList
För MutableList<*> kan du läsa som Any?, men du kan inte skriva alls – kompilatorn förhindrar det.
fun clearFirstElement(list: MutableList<*>) {
if (list.isNotEmpty()) {
list.removeAt(0) // OK: remove by index doesn't need T
// list.add("x") // Error: can't write unknown type
}
}
fun main() {
val m = mutableListOf(1, 2, 3)
clearFirstElement(m)
println(m) // [2, 3]
}Klass med stjärnprojektion
När du kontrollerar typen hos en generisk klass vid körning använder du stjärnprojektion eftersom typargument raderas.
fun isListOfSomething(obj: Any): Boolean {
return obj is List<*> // OK with star
// obj is List<String> // Warning: cannot check erased type
}
fun main() {
println(isListOfSomething(listOf(1, 2))) // true
println(isListOfSomething("not a list")) // false
}Flera stjärnparametrar
En funktion kan ha flera stjärnprojicerade parametrar när den arbetar med par eller mappar av okända typer.
fun describeMap(map: Map<*, *>) {
map.forEach { (k, v) ->
println("${k?.javaClass?.simpleName} -> ${v?.javaClass?.simpleName}")
}
}
fun main() {
describeMap(mapOf("key" to 42, 1 to true))
}När stjärna INTE ska användas
Undvik stjärnprojektion när du behöver skriva till en samling eller när du i stället kan använda en begränsad typparameter – en begränsad typparameter ger dig mer information.
// Bad: loses type information
fun addToStar(list: MutableList<*>, item: Any?) {
// list.add(item) // compile error
}
// Better: use bounded type parameter
fun <T : Any> addTyped(list: MutableList<T>, item: T) {
list.add(item)
}
fun main() {
val l = mutableListOf("a")
addTyped(l, "b")
println(l)
}Stjärna med typkontroller och casts
Använd stjärnprojektion för att utföra instanceof-kontroller på generiska klasser och casta sedan till en specifik typ för det faktiska arbetet.
fun handleResponse(response: Any) {
if (response is List<*>) {
val list = response as List<*>
println("List with ${list.size} elements")
val first = list.firstOrNull()
if (first is String) println("First string: $first")
}
}
fun main() {
handleResponse(listOf("hello", "world"))
handleResponse(42)
}Praktiskt: Generisk händelsedistributör
En distributör som accepterar valfritt Handler<*> men distribuerar typade händelser på ett säkert sätt.
interface Handler<in T> { fun handle(event: T) }
class LogHandler : Handler<Any> {
override fun handle(event: Any) = println("Event: $event")
}
fun dispatch(handler: Handler<*>, event: Any) {
@Suppress("UNCHECKED_CAST")
(handler as Handler<Any>).handle(event)
}
fun main() {
dispatch(LogHandler(), "click")
dispatch(LogHandler(), 42)
}Stjärna i reified-sammanhang
Stjärnprojektion är särskilt vanligt i reflektions- och serialiseringskod där körningstypen inspekteras via KClass<*>.
fun printClassName(klass: kotlin.reflect.KClass<*>) {
println(klass.simpleName)
}
fun main() {
printClassName(String::class) // String
printClassName(List::class) // List
printClassName(Int::class) // Int
}Snabbkontroll
Vilken typ får du när du läser från en List<*>?
Sammanfattning
Stjärnprojektion (*) accepterar alla generiska varianter för skrivskyddad åtkomst. Använd den för typkontroller, generiska verktyg och reflektion. Undvik den när du behöver skriva till en samling eller när en begränsad typparameter ger bättre typsäkerhet.
Lär dig Kotlin med en AI-lärare – gratis
Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.
- Kurser
- 51
- Lektioner
- 203
Vanliga frågor
Är lektionen ”Stjärnprojektion och när * ska användas” gratis?
Ja – du kan läsa vilka 3 lektioner som helst i lärvägen Kotlin Academy, inklusive ”Stjärnprojektion och när * ska användas”, kostnadsfritt i sin helhet här på webben. Därefter låser CoddyKit PRO upp alla lektioner, plus interaktiv övning med en inbyggd kodredigerare och en AI-lärare dygnet runt. Kursen i Kotlin Academy innehåller totalt 4 lektioner.
Vad lär jag mig i ”Stjärnprojektion och när * ska användas”?
Använd stjärnprojektion för okända generiska typer och förstå dess begränsningar. Ni övar på Kotlin Academy med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.
Behöver jag någon erfarenhet för att börja lära mig Kotlin Academy?
Du behöver inga förkunskaper. Utbildningen i Kotlin Academy på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 3 av 4.
Hur lång tid tar lektionen ”Stjärnprojektion och när * ska användas”?
De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.
Kan jag skriva och köra kod i den här Kotlin Academy-lektionen?
Ja. Varje Kotlin Academy-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.
Alla lektioner i den här kursen
- Generiska funktioner och typbegränsningar med where
- Varians vid deklaration: in och out
- Stjärnprojektion och när * ska användas
- Type erasure och reified-typparametrar