ジェネリクスとは
ジェネリクスはあるクラスを作る上で、型の情報を汎用的に持たせるための仕組み。
特にリストやハッシュ等のコレクションは任意の型のインスタンスをまとめることができるが、異なる型の要素を持ってはならないという制約がある。この場合、ジェネリクスを使って型情報を汎用化することで、コンパイラが型の安全性を保証できるようになっている。
書き方
kotlin
class
class Box<T>(t: T) {
var value = t
}
val box: Box<Int> = Box<Int>(1)
パラメータを推測することができる場合には、型引数を省略することができます。
val box = Box(1)
関数
fun <T> singletonList(item: T): List<T> {
// ...
}
fun <T> T.basicToString() : String { // 拡張関数
// ...
}
ジェネリック関数を呼び出すには、関数名の 後に 呼び出し箇所で型引数を指定します。
val l = singletonList<Int>(1)
Java
class Box<T>{
private T t;
public Box(T t){
this.t = t;
}
public T getT(){
return t;
}
}
Box<Integer> box = new ClassSample<Integer>(1);
例
異なる型の共通の処理を書くことができる。
下記のコードは渡されたデータを2回printする処理。
class MyData<T>(private val t: T) {
fun printTwo() {
println(t)
println(t)
}
}
fun main() {
val myStrData = MyData("aaa") //引数に文字列を指定
myStrData.printTwo()
val myIntData = MyData(1) //引数に数値を指定
myIntData.printTwo()
}
実行結果
aaa
aaa
1
1
型制約
パラメータに型制約を持たせることが出来ます。
以下はChildClassクラスとそのサブクラスのみ使用できます。
open class ParentClass
open class ChildClass : ParentClass()
class GrandchildClass : ChildClass()
class Box<T: ChildClass> (t: T) {
var value = t
}
fun main() {
val box1 = Box(ParentClass()) //代入できない
val box2 = Box(ChildClass()) //代入可能
val box3 = Box(GrandchildClass()) //サブクラスなので代入可能
val box4 = Box("String") //型が異なるので代入できない
}