サーチ…
前書き
リストには、数字、単語、または実際に何かを保持することができます。だから私たちはリストを総称と呼んでいます。
ジェネリックスは、基本的には、クラスが保持できる型とオブジェクトが現在保持している型を定義するために使用されます。
構文
- クラスClassName < TypeName >
- クラスClassName <*>
- ClassName <in UpperBound >
- ClassName <out LowerBound >
- クラス名 < TypeName : UpperBound >
パラメーター
パラメータ | 詳細 |
---|---|
TypeName | タイプ汎用パラメータの名前 |
上界 | 共変型 |
LowerBound | コントラバナント型 |
クラス名 | クラスの名前 |
備考
内在する上限はNullableです
Kotlinジェネリックスでは、型パラメータT
上限はAny?
。したがって、このクラスの場合:
class Consumer<T>
型パラメータT
は本当にT: Any?
。非nullの上限を作るには、明示的に特定のT: Any
を使います。例えば:
class Consumer<T: Any>
宣言サイトの分散
宣言サイトの差異は、使用サイトの差異の宣言とみなすことができます。
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
宣言サイトの分散の広範な例は、 List<out T>
であり、これはT
が戻り値の型としてのみ現れるように不変であり、 Comparator<in T>
は引数としてT
を受け取るだけです。
サイト使用差異
使用サイトの差異は、Javaワイルドカードに似ています。
アウトプロジェクション:
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
インプロジェクション:
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
星型投影
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
参照:
Variant JavaからKotlinを呼び出すときの相互運用性。
Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow