Edited at

Kotlinチートシート: Generics編

More than 1 year has passed since last update.

元の記事 → 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