skip to content

Extension Functions

An extension declares a receiver type in its name and accesses it as this, compiling to a static method that takes the receiver as its first parameter. That desugaring explains both why extensions cannot access private members and why they cost nothing at runtime.

part ofKotlinoverview, primer and where to startread it →
on this pageshow

questions

5

What is an extension function in Kotlin, and how do you declare one?

level: juniorimportance: must knowfreq 85%

answer

  1. Receiver type goes before the dot: fun Type.name()
  2. Inside the body, this = the receiver object
  3. Call with normal dot syntax, like a member
  4. Class is NOT modified — just convenient syntax
  5. Usually top-level + imported

basics

~20 s

An extension function lets you add a new function to an existing type without changing its source. You write the type name before the function name, like fun String.shout(), and call it as if it were a normal method.

solid answer

~40 s

An extension function adds behavior to a type you don't own (or can't modify) without inheritance or wrapping. You declare it by prefixing the function name with a receiver type: `fun String.shout(): String = this.uppercase() + "!"`. Inside the body, `this` refers to the receiver instance (the String here), and `this` can be omitted for member access. You call it with normal dot syntax: `"hi".shout()`. The class is not actually modified — the function is resolved statically. Extensions are commonly declared as top-level functions in a file and imported where needed. They are a core Kotlin idiom for building readable, fluent helper APIs (the standard library is full of them, e.g. `List.firstOrNull()`).

code

kotlin · 6 lines
kotlin
fun Int.isEven(): Boolean = this % 2 == 0

fun main() {
    println(4.isEven())  // true
    println(7.isEven())  // false
}

go deeper

for a junior

Can declare fun Type.name(), knows this is the receiver, and calls it with dot syntax.

for a middle

Explains it does not mutate the class and is a top-level, importable helper for readable APIs.

for a senior

Frames extensions as compile-time sugar with no runtime class modification and discusses visibility limits.

for a principal

Positions extensions in API design (fluent helpers vs members) and the trade-offs versus members for evolvable libraries.

## What an extension function is An **extension function** is a function declared *outside* a class but callable *as if* it were a member of that class. It lets you "add" a function to a type you cannot or do not want to modify — a JDK class, a library type, or even your own class — without subclassing, the Decorator pattern, or editing the original source. ## Declaring one The syntax puts the **receiver type** (the type being extended) before the function name, separated by a dot: ```kotlin fun String.shout(): String = this.uppercase() + "!" fun main() { println("hello".shout()) // HELLO! } ``` - `String` here is the **receiver type**. - The actual object the function is called on (`"hello"`) is the **receiver object**. - Inside the body, the keyword **`this`** refers to the receiver object. As with members, `this` is implicit, so `uppercase() + "!"` works without writing `this.`. ## Where you declare them Most extensions are **top-level** functions in a `.kt` file, so they can be imported anywhere: ```kotlin // in StringExtensions.kt package com.example.util fun String.shout() = uppercase() + "!" ``` Callers add `import com.example.util.shout`. You can also declare extensions inside a class or object, but top-level is the common, reusable form. ## Key mental model An extension does **not** modify the class and does **not** insert anything into the type's method table. It is pure syntactic convenience that the compiler resolves at compile time. This is why extensions are great for *helpers* (formatting, conversions, small computations) but cannot, for example, access `private` members of the receiver type.

  • Does an extension function actually add the method to the class?
    No. The class is untouched; the function is resolved at compile time. It only looks like a member at the call site.
  • Can an extension access private fields of the receiver type?
    No. It only sees the public (and, within the same file/module, internal) API of the receiver, because it lives outside the class.

Like a sticky note of helper instructions attached to an object — the object itself is unchanged, but anyone reading it can follow the extra notes.

saying these in an interview costs you the question

  • Claiming the extension modifies or reopens the original class
  • Saying it works via inheritance or runtime patching
  • Thinking extensions can read the receiver's private members
  • Not knowing 'this' refers to the receiver inside the body

context

open as a page

Extensions don't modify the class, so how does Kotlin compile an extension function under the hood?

level: middleimportance: must knowfreq 70%

basics

~10 s

Kotlin compiles an extension into a plain static method. The object you call it on is just passed as the first hidden argument. So a.foo() really becomes Foo.foo(a) at the bytecode level.

open as a page

Inside an extension function body, what does `this` refer to, and how do you access the receiver explicitly?

level: juniorimportance: should knowfreq 55%

basics

~20 s

Inside the body, this is the object the function was called on (the receiver). You can write this to refer to it, or just call its members directly without this, like in a normal method.

open as a page

When should you reach for an extension function versus a member function or a utility class, and what are the design trade-offs?

level: middleimportance: should knowfreq 50%

basics

~20 s

Use an extension when you want a method-like helper on a type you don't own or want to keep the class small, and the helper only needs the type's public API. Use a member when it needs private state or should be overridable.

open as a page

How do visibility modifiers apply to extension functions — what can a private/internal/member extension see and be seen by?

level: seniorimportance: should knowfreq 45%

basics

~20 s

An extension follows normal visibility rules for where it is declared, not the type it extends. A top-level public extension is usable anywhere; a private one only in its file. Because it sits outside the class, it can only see that type's public members.

open as a page