Verwendungsseitige Varianz
Typ-Projektionen
Verwendungsseitige Varianz 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.
Varianz an der Verwendungsstelle
Manchmal ist eine generische Klasse insgesamt invariant, aber eine bestimmte Funktion erzeugt den Typ ausschließlich oder akzeptiert ihn ausschließlich als Eingabe. Die Varianz an der Verwendungsstelle, auch Typprojektion genannt, wendet out oder in direkt an der Stelle an, an der ein Typ verwendet wird.
Warum Varianz an der Verwendungsstelle?
Eine invariante Klasse wie MutableList<T> kann bei ihrer Deklaration nicht kovariant gemacht werden, weil sie T sowohl liest als auch schreibt. Eine bestimmte Funktion liest möglicherweise nur daraus; Projektionen ermöglichen es, dies sicher auszudrücken.
out-Projektion
Wenn Sie Array<out T> als Parametertyp schreiben, erhalten Sie eine kovariante Sicht: Sie können T lesen, aber nicht schreiben. Dadurch können Sie ein Array<String> übergeben, wenn ein Array<out Any> erwartet wird.
fun printArray(items: Array<out Any>) {
for (item in items) println(item)
}
fun main() {
val names: Array<String> = arrayOf("Ann", "Bob")
printArray(names)
}Nur lesen
Bei einer out-Projektion erlaubt der Compiler das Lesen (Ausgabe), verbietet aber das Schreiben (Eingabe), weil das Schreiben die Typsicherheit des ursprünglichen Arrays verletzen könnte.
in-Projektion
Wenn Sie Array<in T> schreiben, erhalten Sie eine kontravariante Sicht: Sie können T hineinschreiben, aber beim Lesen erhalten Sie Werte als Any?. Dadurch können Sie Arrays von T oder einem beliebigen Supertyp akzeptieren.
fun fill(dest: Array<in Int>, value: Int) {
for (i in dest.indices) dest[i] = value
}
fun main() {
val numbers: Array<Number> = arrayOf(0, 0, 0)
fill(numbers, 7)
println(numbers.toList())
}Nur schreiben
Bei einer in-Projektion dürfen Sie Werte vom Typ T schreiben (Eingabe). Beim Lesen wird der Elementtyp jedoch als oberster Typ betrachtet, da der tatsächliche Elementtyp ein beliebiger Supertyp sein könnte.
Projektionen und Varianz an der Deklarationsstelle
Die Varianz an der Deklarationsstelle (class Box<out T>) gilt überall, wo die Klasse verwendet wird. Typprojektionen an der Verwendungsstelle (Box<out T> als Parameter) gelten nur an dieser einen Stelle. Verwenden Sie Projektionen, wenn die Klasse selbst invariant bleiben muss.
Die Sternprojektion
Wenn der Typ-Parameter für Sie überhaupt keine Rolle spielt, verwenden Sie die Sternprojektion *. List<*> bezeichnet eine Liste mit einem unbekannten Typ. Sie können die Elemente als obere Schranke lesen, aber nicht sicher in die Liste schreiben.
fun printSize(collection: List<*>) {
println("Size: ${collection.size}")
}
fun main() {
printSize(listOf(1, 2, 3))
printSize(listOf("a", "b"))
}Grenzen der Sternprojektion
Mit * können Sie weiterhin typunabhängige Member wie size aufrufen und Elemente als Any? lesen. Sie können jedoch keine Elemente hinzufügen, weil der tatsächliche Typ unbekannt ist.
fun main() {
val unknown: List<*> = listOf("x", "y")
val first: Any? = unknown.first()
println(first)
}Die richtige Projektion wählen
Verwenden Sie out T, wenn eine Funktion nur liest, in T, wenn sie nur schreibt, und *, wenn der genaue Typ keine Rolle spielt. Diese Projektionen machen invariante Klassen auf flexible und typsichere Weise nutzbar.
Beziehung zu Java-Wildcards
Die Projektionen out T und in T in Kotlin entsprechen den Java-Wildcards ? extends T und ? super T. Wenn Sie die Generics von Java kennen, werden Ihnen Projektionen vertraut vorkommen.
Kurze Überprüfung
Was können Sie mit einem Parameter tun, dessen Typ Array<out Any> ist?
Zusammenfassung
Die Varianz an der Verwendungsstelle wendet Projektionen mit out (nur lesen) oder in (nur schreiben) bei einer bestimmten Verwendung an. * wird als Sternprojektion verwendet, wenn der Typ unbekannt ist. So bleiben invariante Klassen flexibel, ohne ihre Deklaration zu ändern. Als Nächstes schränken Sie Typ-Parameter mit generischen Einschränkungen ein.
Häufig gestellte Fragen
Ist die Lektion „Verwendungsseitige Varianz“ kostenlos?
Ja — der vollständige Text von „Verwendungsseitige Varianz“ 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 „Verwendungsseitige Varianz“?
Typ-Projektionen 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 „Verwendungsseitige Varianz“?
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
- Generische Funktionen und Klassen
- Deklarationsseitige Varianz
- Verwendungsseitige Varianz
- Einschränkungen für generische Typen