LoginSignup
25
17

More than 5 years have passed since last update.

Kotlinチートシート: Generics編

Last updated at Posted at 2018-01-29

元の記事 → Swift to Kotlinチートシート

functionのGenerics

fun <T> get(arg: T): T {
   return arg
}

classのGenerics

class Bar<T> {}

Generics型の制約

class Bar<T: View> {}

複数制約を設ける場合は where で書く。

class Bar<T> where T: View, T: TypeCode {}

何も制約を設けない場合は Any? 扱い。
以下のケースではKClassのTがnullを許容しないので、少なくとも optional を外して、T: Anyにしないとコンパイルが通らない。

fun <T: Any> get(type: KClass<T>) : T {
    return type.java.newInstance()
}

Generics型のインスタンス化

Generics型のインスタンス化はできないっぽい。
以下のようにTypeを受け取ってオブジェクトを作ることはできる。

fun <T: Any> get(type: KClass<T>) : T {
    return type.java.newInstance()
}

Genericsのワイルドカード

Javaで言う Class<?> は アスタリスクを使って Class<*>のように書く。
このアスタリスクはout Any?を表す。
out なのでGenerics型は戻り値にしか使えない。

Generics Typeからクラスオブジェクトを取得する

T::class のように Genericsの型からクラスオブジェクトを取得するのは、基本的に無理。

inline fun <reified T>foo() {
    System.out.println(T::class)
}

上記のようにfunction を inline にしてGenericsの型に reified をつけるとクラスオブジェクトを取得できるが、inlineのファンクションは色々と制限があり、使うのが難しい場合がある。

また、今のところクラスに指定したGenericsパラメータからはクラスオブジェクトを取得する術がないっぽい。

class Foo<T> {
   fun test() {
      // ここで T::class を使うすべがない
   }
}

declaration-site variance

Genericsパラメーターを制約付きWildcardにしたい場合、型の前に out を記載する。

Java
List<? extends Number> b = a;
Swift
val b: ArrayList<out Number> = a

詳細は以下に書いているがまだちゃんと理解できていない。
https://kotlinlang.org/docs/reference/generics.html#variance

25
17
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
25
17