← Back to Kotlin Course | Chapter 11: Generics | Lesson 2 of 6

Generic Functions

A generic function is a recipe that can work on any type of ingredient you hand it, figuring out the type fresh every time it's called.
Syntax
kotlin
fun <T> functionName(param: T): T = param

fun <A, B> functionName(a: A, b: B): ReturnType = expression

functionName(value)
functionName<Type>(value)

Declaring a Generic Function

The type parameter goes in angle brackets right before the function name, letting the function's parameters and return type all refer to that same placeholder type.

Example: Declaring a Generic Function

markup
fun <T> identity(value: T): T = value

// Entry point: execution of the program starts here
fun main() {
    // Print `identity(42)` to the console, with a trailing newline
    println(identity(42))
    // Print `identity("Kotlin")` to the console, with a trailing newline
    println(identity("Kotlin"))
}

Generic Functions on Collections

Generic functions are especially common for working with collections of any element type, such as returning the first two items regardless of what type they are.

Example: Generic Functions on Collections

markup
fun <T> firstTwo(items: List<T>): List<T> = items.take(2)

// Entry point: execution of the program starts here
fun main() {
    // Print `firstTwo(listOf(1, 2, 3, 4))` to the console, with a trailing newline
    println(firstTwo(listOf(1, 2, 3, 4)))
    // Print `firstTwo(listOf("a", "b", "c"))` to the console, with a trailing newline
    println(firstTwo(listOf("a", "b", "c")))
}

Multiple Type Parameters in a Function

A generic function can declare more than one type parameter, useful for operations that combine two different kinds of values into a result.

Example: Multiple Type Parameters in a Function

markup
fun <A, B> combine(a: A, b: B): String = "$a and $b"

// Entry point: execution of the program starts here
fun main() {
    // Print `combine(1, "one")` to the console, with a trailing newline
    println(combine(1, "one"))
    // Print `combine(true, 3.14)` to the console, with a trailing newline
    println(combine(true, 3.14))
}

Without a Constraint, T Is Treated as Any?

With no upper bound specified, T behaves like Any?, so the function can only do things valid for absolutely any type, like storing, returning, or comparing for equality.

Example: Without a Constraint, T Is Treated as Any?

markup
fun <T> printTwice(value: T) {
    // Print `value` to the console, with a trailing newline
    println(value)
    // Print `value` to the console, with a trailing newline
    println(value)
}

// Entry point: execution of the program starts here
fun main() {
    printTwice(100)
    printTwice("hello")
}
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
Common Mistakes
  1. Placing the type parameter after the function name instead of before it; the correct order is fun <T> functionName(...).
  2. Assuming a generic function can perform type-specific operations (like arithmetic) on T without any constraint restricting what T can be.
  3. Redeclaring a type parameter already present on the enclosing class when it is not actually needed for that particular function.
Chapter Summary
  • A generic function declares its type parameter before the function name: fun <T> functionName(...).
  • The type parameter can appear in the parameter list, return type, or body of the function.
  • Without constraints, T is treated as Any?, so only operations valid for any type (like storing or returning it) are allowed.
  • Generic functions let one implementation work correctly and safely across many different types.
🔒

Chapter Quiz — Complete all 6 topics to unlock

0/6 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.