skip to content

provideDelegate

provideDelegate runs once when the delegate is created, so you can validate the property name or choose a different delegate before anything is bound. It is niche, but it is what frameworks use to fail fast at construction rather than first access.

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

questions

5

What is the operator fun provideDelegate, and at what moment does it run relative to a delegated property created with by?

level: juniorimportance: should knowfreq 30%

answer

  1. operator fun, called once at delegate creation
  2. returns the REAL delegate (with getValue/setValue)
  3. gives KProperty before binding -> name checks
  4. thisRef + property: KProperty<*> params
  5. not per-access; runs once

basics

~20 s

It is an optional hook the compiler calls once when a delegated property is set up. Instead of using your object directly as the delegate, Kotlin asks it to hand back the real delegate, so you can check or swap it first.

solid answer

~40 s

provideDelegate is an operator function the compiler invokes at delegate-creation time for a property declared with by. If the right-hand expression's type has an operator fun provideDelegate(thisRef, property), the compiler calls it once and uses its return value as the actual delegate (the object whose getValue/setValue back the property). It runs when the delegate is established: for a member/top-level property that is during the enclosing object's initialization; for a local delegated property at the point the declaration executes. The KProperty<*> argument gives you the property's name and metadata, so you can validate or select a delegate before binding. It does not run on every get/set — only once per property instance.

code

kotlin · 9 lines
kotlin
class Tag(val value: String) {
    operator fun provideDelegate(thisRef: Any?, prop: KProperty<*>): ReadOnlyProperty<Any?, String> {
        println("creating delegate for ${prop.name}")
        return ReadOnlyProperty { _, _ -> value }
    }
}

class Holder { val label: String by Tag("hi") }
// 'creating delegate for label' prints once, when Holder is constructed

go deeper

for a junior

Knows it is an optional hook that runs once and returns the actual delegate.

for a middle

Explains the signature, when it fires relative to object init, and that the return value backs getValue/setValue.

for a senior

Articulates the design intent: pre-binding access to KProperty for validation/selection, and contrasts with lazy first-access checks.

for a principal

Discusses generated field shape (prop$delegate), local vs member timing, and when to expose this in a library API vs keeping it internal.

## What provideDelegate is `provideDelegate` is an **optional operator function** that sits in front of Kotlin's delegated-property machinery. When you write a property with the `by` keyword, the expression after `by` normally becomes the *delegate* — the object that must expose `getValue` (and `setValue` for `var`). `provideDelegate` lets you insert a step **before** that binding: instead of using the right-hand object directly, the compiler asks it to *provide* the delegate. ## Signature ```kotlin operator fun provideDelegate( thisRef: R, // the object owning the property (or null for top-level) property: KProperty<*> ): ActualDelegate ``` - It must be marked `operator`. - `thisRef` is the receiver/owner of the property (the enclosing instance, or `Nothing?`/`null` for top-level/local). - `property` is a `KProperty<*>` carrying reflection metadata — most importantly `property.name`. - The **return value** is the real delegate, which itself must have `getValue`/`setValue`. ## When it runs It runs **once, at delegate-creation time**, not on every access: - For a **member or top-level** property, that is during initialization of the enclosing object (when the constructor/initializer runs). - For a **local** delegated property, at the point the `by` declaration is executed. After `provideDelegate` returns, the compiler stores the returned object (in a hidden `prop$delegate` field) and routes every subsequent `get`/`set` through *that* object's `getValue`/`setValue`. `provideDelegate` is never called again for that property instance. ## Why it exists The key benefit: you get the `KProperty<*>` (hence the property name and annotations) **before** the delegate is bound. That enables **property-name validation** or **selecting which delegate to use** at creation time, rather than discovering a problem lazily on first access. ```kotlin class ResourceLoader(val id: String) { operator fun provideDelegate(thisRef: Any?, prop: KProperty<*>): ReadOnlyProperty<Any?, String> { require(prop.name.startsWith("res")) { "Property ${prop.name} must start with 'res'" } return ReadOnlyProperty { _, _ -> "loaded:$id" } } } class Screen { val resTitle: String by ResourceLoader("title") // validated at construction } ``` Without `provideDelegate`, the `require` could only fire on first read of `resTitle`. With it, the check happens when `Screen` is constructed.

  • Does provideDelegate run on every property read?
    No. It runs once when the delegate is created (object/declaration initialization). Reads and writes afterward go through the returned delegate's getValue/setValue.
  • What must the object returned by provideDelegate provide?
    getValue for a val, and getValue plus setValue for a var — exactly what a normal delegate must provide.

Like a building manager who, before handing you the key (the delegate), checks your name on the tenant list and may give you a different key than you asked for.

saying these in an interview costs you the question

  • Saying provideDelegate runs on every get/set
  • Confusing it with getValue/setValue (it returns the delegate, it isn't the accessor)
  • Thinking it is mandatory for delegation
  • Not knowing it receives a KProperty with the property name

context

open as a page

Show how the compiler desugars `val x: T by expr` when `expr` has a provideDelegate operator, including the hidden field and the KProperty argument.

level: middleimportance: should knowfreq 28%

basics

~20 s

Kotlin creates a hidden field for the delegate. If provideDelegate exists, it first calls expr.provideDelegate(owner, property) and stores that result in the field. Then every read calls getValue on that stored field, passing the owner and the property metadata.

open as a page

Give a realistic use case where provideDelegate is the right tool, and explain why moving validation into it beats validating inside getValue.

level: middleimportance: should knowfreq 22%

basics

~20 s

Use it when you must check something about the property at setup time, like its name, and want to fail fast when the object is built rather than later on first use. Checking in getValue only fails when the property is first read, which may be much later or never.

open as a page

What are the timing and correctness pitfalls of provideDelegate — e.g., touching thisRef state inside it, ordering with other initializers, and the cost of throwing there?

level: seniorimportance: nice to knowfreq 10%

basics

~20 s

It runs while the owning object is still being built, so the object may be only partly initialized. Reading other fields from thisRef can give defaults or nulls. Throwing inside it aborts construction. Keep it side-effect-light and don't rely on later fields.

open as a page

How can provideDelegate select among different delegate implementations at creation time? Sketch an implementation that picks a delegate based on the property's annotations or name.

level: seniorimportance: nice to knowfreq 14%

basics

~20 s

Because provideDelegate returns the real delegate, it can inspect the property and return different delegate objects for different properties. For example, look at the property's name or annotations and return a cached, computed, or read-only delegate accordingly.

open as a page