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 { ... }