What does it mean that a Kotlin lambda 'closes over' a variable, and what can a lambda do with a captured local variable that a Java lambda cannot?
answer
- Closure = lambda + captured enclosing scope
- Kotlin can mutate captured var; Java cannot
- Captures vals, vars, params, outer this
- Same variable shared inside and outside
- State survives after enclosing fn returns
basics
~10 sA Kotlin lambda can read and remember variables from the function around it. Unlike Java, it can also change a captured var, not just read it.
solid answer
~40 sA closure is a lambda (or anonymous function) that captures and retains references to variables from its enclosing scope — function locals, parameters, or outer this. It can use them even after the enclosing function returns. The key difference from Java: Java only allows capturing values that are final or effectively final (read-only). Kotlin lets a lambda capture a var and reassign it; the change is visible both inside the lambda and to the surrounding code, because both share the same captured variable. This works for both inline and non-inline lambdas (with non-inline ones the compiler boxes the var into a Ref wrapper object). You capture vals too — the common, idiomatic case.
code
kotlin · 11 linesfun makeAccumulator(): (Int) -> Int {
var total = 0 // captured mutable var
return { delta ->
total += delta // mutating captured var — allowed in Kotlin
total
}
}
val acc = makeAccumulator()
println(acc(5)) // 5
println(acc(3)) // 8go deeper
Knows a lambda can use variables from the surrounding function and that Kotlin allows mutating a captured var.
Explains that inside and outside share the same variable, and gives the Java effectively-final contrast precisely.
Connects capture to higher-order functions/callbacks and notes the val vs var capture distinction and lifetime beyond the enclosing call.
Frames closures as the foundation for callbacks/coroutines and discusses capture's implications for memory, identity, and design clarity.
## What a closure is A **closure** is a function value — a **lambda** (`{ ... }`) or **anonymous function** (`fun(...) { ... }`) — that **captures** variables from the scope where it is defined. "Captures" means it keeps a reference to those variables so it can read (and sometimes write) them, even if the lambda runs later, after the enclosing function has already returned. The set of variables a lambda can see and remember is its *captured environment*. Captured things include: - local `val`/`var` declared in the enclosing function - function parameters - the enclosing `this` (the receiver of the outer method) ## The Java difference In **Java**, a lambda or anonymous class may only capture variables that are `final` or *effectively final* — i.e. never reassigned after initialization. You cannot mutate a captured local from inside a Java lambda; it is a compile error. In **Kotlin**, a lambda can capture a `var` **and reassign it**, and the new value is visible both inside the lambda and outside it. Both sides refer to the *same* variable. ```kotlin fun countClicks(): () -> Int { var count = 0 // captured var return { count += 1 // mutate the captured var — legal in Kotlin, illegal in Java count } } val click = countClicks() println(click()) // 1 println(click()) // 2 — state persists in the closure ``` ## Capturing val (the common case) Most real code captures a read-only `val`: ```kotlin fun greeter(name: String): () -> Unit = { println("Hello, $name") } ``` Here `name` is captured by value-semantics (it never changes), and the returned lambda remembers it. ## Why this matters Closures are what make higher-order functions like `map`, `filter`, `forEach`, callbacks, and coroutines convenient — they let a small function body reach out and use surrounding context without you threading every value through parameters.
- Does the captured var's change made inside the lambda affect the outer function's view of that variable?Yes. The lambda and the enclosing scope share the same variable, so a reassignment inside the lambda is visible outside it (and vice versa).
- Can an anonymous function (fun(...) {}) capture variables the same way?Yes — anonymous functions are also closures and capture enclosing scope identically to lambdas.
A closure is like a backpack the lambda carries: it packs the variables it needs from home and can still use them anywhere it travels.
saying these in an interview costs you the question
- Claiming Kotlin lambdas, like Java, can only capture final/read-only variables
- Saying captured vars are copied so outer code never sees the change
- Thinking only top-level/global variables can be captured
- Confusing closure (captures scope) with a plain function reference