Suche…


Einführung

Eine Liste kann Zahlen, Wörter oder wirklich alles enthalten. Deshalb nennen wir die Liste generisch .

Generics werden im Allgemeinen verwendet, um zu definieren, welche Typen eine Klasse enthalten kann und welchen Typ ein Objekt derzeit enthält.

Syntax

  • Klasse Klassenname < Typname >
  • Klasse ClassName <*>
  • ClassName <in UpperBound >
  • ClassName <out LowerBound >
  • Klassenname <Typename: Upperbound>

Parameter

Parameter Einzelheiten
Modellname Typ Name des generischen Parameters
Obere Grenze Kovarianter Typ
LowerBound Kontravarianter Typ
Klassenname Name der Klasse

Bemerkungen

Implizite obere Grenze ist nullfähig

In Kotlin Generics wäre die Obergrenze des Typparameters T Any? . Deshalb für diese Klasse:

class Consumer<T>

Der Typparameter T ist wirklich T: Any? . Um eine nicht-nullfähige Obergrenze festzulegen, explizit ein bestimmtes T: Any . Zum Beispiel:

class Consumer<T: Any>

Deklaration-Site-Abweichung

Deklarationsstellenabweichung kann als Deklaration der Verwendungsstellenabweichung einmal und für alle Verwendungsstellen verstanden werden.

  class Consumer<in T> { fun consume(t: T) { ... } }

  fun charSequencesConsumer() : Consumer<CharSequence>() = ...

  val stringConsumer : Consumer<String> = charSequenceConsumer() // OK since in-projection
  val anyConsumer : Consumer<Any> = charSequenceConsumer() // Error, Any cannot be passed
  
  val outConsumer : Consumer<out CharSequence> = ... // Error, T is `in`-parameter

Weit verbreitete Beispiele für die Abweichung von Deklarationsstellen sind List<out T> , die unveränderlich ist, sodass T nur als Rückgabewerttyp angezeigt wird, und Comparator<in T> , der nur T als Argument empfängt.

Abweichung der Verwendungsstelle

Die Abweichung bei der Verwendung von Websites ähnelt Java-Platzhaltern:

Out-Projektion:

  val takeList : MutableList<out SomeType> = ... // Java: List<? extends SomeType>

  val takenValue : SomeType = takeList[0] // OK, since upper bound is SomeType

  takeList.add(takenValue) // Error, lower bound for generic is not specified

In-Projektion:

  val putList : MutableList<in SomeType> = ... // Java: List<? super SomeType>
  
  val valueToPut : SomeType = ...
  putList.add(valueToPut) // OK, since lower bound is SomeType

  putList[0] // This expression has type Any, since no upper bound is specified

Sternprojektion

  val starList : MutableList<*> = ... // Java: List<?>

  starList[0] // This expression has type Any, since no upper bound is specified
  starList.add(someValue) // Error, lower bound for generic is not specified

Siehe auch:



Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow