サーチ…


前書き

リストには、数字、単語、または実際に何かを保持することができます。だから私たちはリストを総称と呼んでいます。

ジェネリックスは、基本的には、クラスが保持できる型とオブジェクトが現在保持している型を定義するために使用されます。

構文

  • クラスClassName < TypeName >
  • クラスClassName <*>
  • ClassName <in UpperBound >
  • ClassName <out LowerBound >
  • クラス < TypeNameUpperBound >

パラメーター

パラメータ詳細
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