Kotlin
Generics
Sök…
Introduktion
En lista kan innehålla siffror, ord eller egentligen vad som helst. Det är därför vi kallar listan generisk .
Generics används i princip för att definiera vilka typer en klass kan innehålla och vilken typ ett objekt för närvarande har.
Syntax
- klass Klassnamn < Typnamn >
- klass Klassnamn <*>
- Klassnamn <i UpperBound >
- Klassnamn <ut LowerBound >
- klass Namn < Type Namn : UpperBound >
parametrar
Parameter | detaljer |
---|---|
Typename | Typ Namn på generisk parameter |
Övre gräns | Covariant typ |
nedregräns | Contravariant Type |
Klassnamn | Klassens namn |
Anmärkningar
Implicit Upper Bound är nullable
I Kotlin Generics skulle den övre gränsen för typparameter T
vara Any?
. Därför för denna klass:
class Consumer<T>
Typparametern T
är verkligen T: Any?
. För att göra en icke-nullable övre gräns, uttryckligen specifik T: Any
. Till exempel:
class Consumer<T: Any>
Varians för deklarationsplats
Varians för deklarationsplatser kan betraktas som en deklaration om användningsplatsvarians en gång för alla användningsplatser.
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
Utbredda exempel på varianter mellan deklarationssidorna är List<out T>
, som är oföränderlig så att T
endast visas som returtypstyp, och Comparator<in T>
, som bara får T
som argument.
Avvikelse på användningssidan
Användningsplatsvariansen liknar Java jokertecken:
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
Star-projektion
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
Se även:
Interoperabilitet för Variant Generics när du ringer Kotlin från Java.