Extension Functions
Kotlin's "extension functions" let you add methods to existing classes without inheriting from them. You define an extension function as a regular function with a receiver type (the type being extended), and call it just like a method of that class.
Syntax
// Defining an extension function (extending String)
fun String.hello(): String = "Hello, $this!"
// Calling it
"Kotlin".hello() // "Hello, Kotlin!"
// Extension function with a parameter
fun String.repeat(n: Int): String = this.repeat(n)
// Extension property (getter only)
val String.wordCount: Int
get() = this.split(" ").size
// Extension function on a nullable type
fun String?.isNullOrBlankCustom(): Boolean = this == null || this.isBlank()
Syntax Reference
| Syntax | Description |
|---|---|
| fun TypeName.functionName() | Defines an extension function. The "TypeName." part specifies the receiver type. |
| this | Refers to the receiver object (the caller) inside an extension function. |
| val TypeName.propertyName | Defines an extension property. It cannot hold state and only supports a getter. |
| Nullable extension function | Using "Type?" as the type name allows the function to be called even on null values. |
Sample Code
// String extension functions
fun String.isPalindrome(): Boolean = this == this.reversed()
fun String.capitalize2(): String = if (isEmpty()) this else this[0].uppercaseChar() + substring(1)
fun String.words(): List<String> = this.trim().split(Regex("\\s+"))
// Int extension functions
fun Int.isPositive(): Boolean = this > 0
fun Int.factorial(): Long {
require(this >= 0) { "Factorial is not defined for negative numbers" }
return if (this <= 1) 1L else (1..this).fold(1L) { acc, i -> acc * i }
}
// Extension properties
val String.wordCount: Int
get() = if (isBlank()) 0 else words().size
val Int.isOdd: Boolean
get() = this % 2 != 0
// List extension function
fun <T> List<T>.secondOrNull(): T? = if (size >= 2) this[1] else null
fun main() {
// String extension functions
println("racecar".isPalindrome()) // true
println("hello".isPalindrome()) // false
println("hello world".capitalize2()) // Hello world
val sentence = " Hello Kotlin World "
println(sentence.words()) // [Hello, Kotlin, World]
println(sentence.wordCount) // 3
// Int extension functions
println(5.isPositive()) // true
println((-3).isPositive()) // false
println(5.factorial()) // 120
println(7.isOdd) // true
// List extension function
val list = listOf("a", "b", "c")
println(list.secondOrNull()) // b
println(emptyList<String>().secondOrNull()) // null
// Used like standard library functions
val numbers = listOf(1, 2, 3, 4, 5)
println(numbers.filter { it.isOdd }) // [1, 3, 5]
}
Overview
Extension functions let you call Java-style utility class methods (e.g., StringUtils.isNotEmpty()) with method-like syntax. After compilation, they are expanded as static functions, so they do not actually modify the class or override any of its members.
Generic extension functions like fun <T> List<T>.xxx() let you add general-purpose methods that abstract over types. Most of Kotlin's standard library functions — including map() and filter() — are implemented as extension functions.
For basic function definitions, see fun — Defining Functions. For higher-order functions, see Higher-Order Functions.
If you find any errors or copyright issues, please contact us.