Skip to content

Delegation and delegated properties

Delegation and Delegated Properties Deep Dive

Overview

Delegation is one of Kotlin's strongest language features for reducing boilerplate and favoring composition.


Core Concepts

Class delegation

interface Printer {
    fun print()
}

class ConsolePrinter : Printer {
    override fun print() = println("print")
}

class Screen(printer: Printer) : Printer by printer

This forwards interface implementation automatically.

Property delegation

val config by lazy { loadConfig() }

The delegate owns access behavior.


Internal Implementation

Delegated properties are compiled into calls to delegate operators such as:

  • getValue()
  • setValue()

Class delegation similarly becomes generated forwarding methods.

So Kotlin removes boilerplate, but the underlying implementation still uses regular method calls and generated glue.


JVM / Compiler Behavior

lazy uses a delegate implementation chosen by thread-safety mode.

Common modes:

  • synchronized (default)
  • publication
  • none

This matters in interview discussions because β€œlazy” behavior is not one-size-fits-all.


Code Examples

lazy

val repository by lazy(LazyThreadSafetyMode.NONE) {
    UserRepository()
}

Observable property

var count: Int by Delegates.observable(0) { _, old, new ->
    println("$old -> $new")
}

Common Interview Questions

  • Q: Why is delegation better than inheritance here? A: Tie Kotlin language features to production outcomes: safety, readability, testability, and runtime or allocation tradeoffs when relevant.
  • Q: How does lazy behave with threads? A: Lead with correctness then throughput: choose dispatcher by workload type, keep critical sections small, cap parallelism, and monitor tail latency and queue depth.
  • Q: What methods must a custom delegate implement? A: Tie Kotlin language features to production outcomes: safety, readability, testability, and runtime or allocation tradeoffs when relevant.

Production Considerations

Delegation is excellent for:

  • reusable behaviors
  • view binding style patterns
  • state observation
  • lightweight wrappers

But hidden magic can hurt readability if overused.


Performance Insights

Delegation reduces manual boilerplate but still introduces generated calls. In most app code the clarity benefit outweighs the tiny indirection cost.


Senior-Level Insights

Strong candidates explain delegation as a language-supported composition mechanism, not just β€œsyntactic sugar.” That distinction matters in architecture discussions.