When should you reach for an object expression versus a lambda / SAM conversion when supplying an interface implementation in Kotlin?
answer
- Single abstract method + Java/fun interface -> lambda (SAM)
- Multi-method / multi-supertype / class extension -> object expression
- Plain Kotlin interface needs fun interface for SAM
- Object expr allocates each eval; non-capturing lambda may be cached
- Extra state -> object expression
basics
~20 sUse a lambda when the interface has a single method and you only need that one method. Use an object expression when you must implement several methods, keep state, or override members of a class.
solid answer
~40 sIf the target is a **functional (SAM) interface** — one abstract method — and you only need to supply that method, prefer a **lambda**: it's terser and, for Kotlin `fun interface`s or Java SAM types, the compiler does a **SAM conversion**. You can't use a plain lambda for a multi-method interface or to override members of an open/abstract **class**; there you need an **object expression**, which can implement several methods, add state and helper members, and call `super`. Object expressions also let you implement **multiple supertypes** at once. A subtle runtime difference: each evaluation of an object expression allocates a new instance; lambdas that capture nothing may be cached/optimized by the compiler. Choose lambdas for single-method callbacks; choose object expressions for richer, multi-member, or class-extending implementations.
code
kotlin · 11 linesfun interface Transformer { fun apply(x: Int): Int }
// SAM conversion: lambda allowed because of 'fun interface'
val doubler: Transformer = Transformer { it * 2 }
// Object expression needed: two methods
interface Lifecycle { fun start(); fun stop() }
val lc = object : Lifecycle {
override fun start() = println("start")
override fun stop() = println("stop")
}go deeper
Picks a lambda for simple single-method callbacks; may not know the fun interface nuance.
Knows lambdas need a SAM/fun interface and that multi-method or class cases require an object expression.
Articulates the fun interface requirement, multiple-supertype and class-extension cases, and the allocation/caching nuance.
Weighs API ergonomics (defining fun interface for lambda-friendliness) against multi-method designs, and considers allocation in hot paths.
## The decision **Lambda / SAM conversion** fits when: - The target is a **functional interface**: one abstract method. This includes Java SAM types and Kotlin **`fun interface`** types. - You only need to provide that **one** method. ```kotlin val r = Runnable { println("hi") } // SAM conversion from a lambda val c = Comparator<Int> { a, b -> a - b } // SAM conversion (Java functional interface) ``` Note: Kotlin only performs SAM conversion for **Java** interfaces or interfaces declared **`fun interface`**. A regular Kotlin interface with one method does **not** auto-convert from a lambda unless marked `fun interface`. **Object expression** fits when you need any of: - To implement an interface with **more than one** abstract method. - To implement **multiple supertypes** at once. - To **extend a class** (open/abstract) and override its members, possibly calling `super`. - To carry **extra state or helper members** beyond the single method. ```kotlin val listener = object : MouseListener { // multi-method interface override fun onClick() {} override fun onHover() {} private var clicks = 0 // extra state } ``` ## Allocation / performance nuance - Each time an **object expression** is evaluated it **allocates a new instance**. - A **non-capturing lambda** may be compiled to a **singleton** (cached) instance; a capturing one allocates per capture. So in hot paths, a non-capturing lambda can be cheaper than an equivalent object expression. ## Readability - One method, no state -> lambda is clearer. - Several methods or state -> object expression keeps it organized and avoids forcing everything into one function. ## Quick rule > Single method, single interface, no extra state -> **lambda** (SAM). Otherwise -> **object expression**.
- Why can't you pass a lambda to a single-method *Kotlin* interface by default?Kotlin only auto-converts lambdas for Java SAM types or interfaces marked `fun interface`; a plain Kotlin interface requires the `fun interface` modifier to enable SAM conversion.
- Is there a performance difference between the two?An object expression allocates a new instance on each evaluation, while a non-capturing lambda may be optimized to a cached singleton, so lambdas can be cheaper in hot paths.
saying these in an interview costs you the question
- Saying any single-method Kotlin interface accepts a lambda without `fun interface`
- Claiming lambdas can override class members or multiple methods
- Ignoring that object expressions allocate per evaluation
- Asserting there is never any performance difference
- Not recognizing multi-method interfaces require an object expression