Kotlin Academy · Lektion

Star Projection und wann * verwendet wird

Wenden Sie Star Projection für unbekannte generische Typen an und verstehen Sie ihre Grenzen.

Lektion 3 von 413 Schritte

Star Projection und wann * verwendet wird ist eine kostenlose Kotlin Academy-Lektion auf CoddyKit. Dies ist Lektion 3 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des Kotlin Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der Kotlin Academy-Kurs umfasst insgesamt 4 Lektionen.

Was ist eine Star-Projektion?

Die Star-Projektion (*) ist in Kotlin die Möglichkeit auszudrücken: „ein generischer Typ mit einem unbekannten Typargument“. Sie ist das sichere Äquivalent zu Javas Raw Type oder einer unbeschränkten 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"))
}

Lesen aus Star-projizierten Typen

Aus einer List<*> können Sie Elemente als Any? lesen. Sie können keine Elemente hinzufügen, weil der tatsächliche Typ unbekannt ist.

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))
}

Star vs. out Any

List<*> und List<out Any?> sind äquivalent. Die Star-Projektion ist eine Kurzform für die kovariante Projektion mit der oberen Schranke.

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
}

Star in Funktionsparametern

Verwenden Sie * in Funktionssignaturen, wenn Sie jede generische Variante akzeptieren müssen, aber nur Methoden aufrufen, für die T nicht bekannt sein muss.

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))
}

Star mit MutableList

Bei MutableList<*> können Sie als Any? lesen, aber überhaupt nicht schreiben – der Compiler verhindert dies.

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]
}

Klasse mit Star-Projektion

Verwenden Sie beim Prüfen des Typs einer generischen Klasse zur Laufzeit eine Star-Projektion, weil Typargumente gelöscht werden.

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
}

Mehrere Star-Parameter

Eine Funktion kann mehrere star-projizierte Parameter besitzen, wenn sie mit Pairs oder Maps unbekannter Typen arbeitet.

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))
}

Wann Sie Star NICHT verwenden sollten

Vermeiden Sie Star-Projektionen, wenn Sie in eine Collection schreiben müssen oder stattdessen einen beschränkten Typparameter verwenden können – ein beschränkter Typparameter liefert mehr Informationen.

// 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)
}

Star mit Typprüfungen und Casts

Verwenden Sie die Star-Projektion für instanceof-Prüfungen bei generischen Klassen und casten Sie anschließend für die eigentliche Verarbeitung auf einen konkreten Typ.

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)
}

Praktisch: Generischer Event-Dispatcher

Ein Dispatcher, der jedes Handler<*> akzeptiert, aber typisierte Events sicher verteilt.

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)
}

Star in reified-Kontexten

Star-Projektionen kommen besonders häufig in Reflection- und Serialisierungscode vor, wenn der Laufzeittyp über KClass<*> untersucht wird.

fun printClassName(klass: kotlin.reflect.KClass<*>) {
    println(klass.simpleName)
}
fun main() {
    printClassName(String::class)     // String
    printClassName(List::class)       // List
    printClassName(Int::class)        // Int
}

Schnelltest

Welchen Typ erhalten Sie beim Lesen aus einer List<*>?

Zusammenfassung

Star-Projektion (*) akzeptiert jede generische Variante für den schreibgeschützten Zugriff. Verwenden Sie sie für Typprüfungen, generische Hilfsfunktionen und Reflection. Vermeiden Sie sie, wenn Sie in eine Collection schreiben müssen oder ein beschränkter Typparameter eine bessere Typsicherheit bietet.

Kostenlos starten

Lerne Kotlin mit einem KI-Tutor — kostenlos

Schreibe und führe echten Code in deinem Browser aus, bekomme sofortige Hilfe von einem 24/7 KI-Tutor und setze dein Lernen im Web oder in der App fort.

Kurse
51
Lektionen
203

Häufig gestellte Fragen

Ist die Lektion „Star Projection und wann * verwendet wird“ kostenlos?

Ja — der vollständige Text von „Star Projection und wann * verwendet wird“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des Kotlin Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der Kotlin Academy-Kurs umfasst insgesamt 4 Lektionen.

Was lerne ich in „Star Projection und wann * verwendet wird“?

Wenden Sie Star Projection für unbekannte generische Typen an und verstehen Sie ihre Grenzen. Du übst Kotlin Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.

Brauche ich Erfahrung, um Kotlin Academy zu starten?

Keine Vorkenntnisse erforderlich. Kotlin Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 3 von 4.

Wie lange dauert die Lektion „Star Projection und wann * verwendet wird“?

Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.

Kann ich in dieser Kotlin Academy-Lektion Code schreiben und ausführen?

Ja. Jede Kotlin Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.

Alle Lektionen in diesem Kurs

  1. Generische Funktionen und Typbeschränkungen mit where
  2. Varianz an der Deklarationsstelle: in und out
  3. Star Projection und wann * verwendet wird
  4. Type Erasure und reifizierte Typparameter
← Zurück zu Kotlin Academy