Kotlin Generics
Generic classes
By receiving an argument as type Any and storing it in a property of type Any, you can define classes or functions for various types such as Int, Char, and String.
class Foo(val value: Any)
fun main() {
val a1 = Foo(123)
println(a1.value) // 123
}
However, because value is type Any, an error occurs if you try to perform a + 1 operation on value as shown below.
class Foo(val value: Any)
fun main() {
val a1 = Foo(123)
println(a1.value + 1) // Error
}
By defining a generic type with <T>, value is treated as a property of the type corresponding to the argument, such as Int, Char, or String, which solves this problem.
class Foo<T>(val value: T)
fun main() {
val a1 = Foo(123)
println(a1.value + 1) // 124
}
You can restrict the type as shown below. In this example, it is restricted to subclasses of Number such as Int and Double.
class Foo<T: Number>(val value: T)
Generic functions
Generics can also be used in functions. The following function receives an argument of any type T and returns a value of type T.
fun <T> foo(x: T): T { ... }
You can specify the type at call time, but omit it when the type is clear from the argument.
foo<Int>(123)
foo<String>("ABC")
foo(123)
foo("ABC")
You can restrict the type as shown below. In this example, it is restricted to subclasses of Number such as Int and Double.
fun <T: Number> foo(x: T): T { ... }
Use where to specify multiple constraints.
fun <T> foo(x: T) where T: Runnable, T: Cancellable { ... }