skip to content

What information does the `KProperty<*>` argument carry into a delegate, and how is it commonly used? Show how a map-backed delegate uses it.

level: middleimportance: should knowfreq 45%

answer

  1. KProperty = reflective property metadata
  2. property.name is the workhorse member
  3. Map delegate looks up this[property.name]
  4. one delegate serves many props via name
  5. star-project as KProperty<*>

basics

~10 s

It is a small description of the property being accessed — mainly its name and type. A common use is property.name to look up the right key, so one delegate can serve many properties.

solid answer

~40 s

The second parameter, a `KProperty<*>`, is reflective metadata about the *declared* property, supplied automatically by the compiler at each access site. The most-used member is `property.name` (a `String`); `KProperty` also exposes the return type, annotations, visibility and isConst/isLateinit flags. Because the same delegate instance receives a different `property` per property it serves, a single delegate can disambiguate — that is exactly how the stdlib `Map`/`MutableMap` delegate works: `getValue` does `this[property.name]` to fetch the entry. The compiler creates these `KProperty` references cheaply (a synthetic property reference per site), so it isn't a full reflective scan. You typically star-project as `KProperty<*>` because you rarely need the precisely reified property type inside the delegate.

code

kotlin · 8 lines
kotlin
// stdlib-style map delegation
class Config(private val src: MutableMap<String, Any?>) {
    var host: String by src
    var port: Int by src
}
val cfg = Config(mutableMapOf("host" to "x", "port" to 80))
cfg.port = 8080 // setValue: src["port"] = 8080
println(cfg.port) // 8080

go deeper

for a junior

Knows the second argument names the property and you can read property.name.

for a middle

Uses property.name correctly and explains the Map delegate keying on it.

for a senior

Distinguishes per-site synthetic property references from runtime reflection and lists other KProperty members.

for a principal

Reasons about when name-based keying is fragile (refactors/obfuscation) and alternatives for robust mapping.

## What KProperty is `KProperty<out V>` is part of Kotlin's **reflection** API (`kotlin.reflect`). It represents a property as a first-class object. When the compiler desugars a delegated access, it passes a reference to the delegated property as this argument. You almost always declare the parameter as `KProperty<*>` (star projection) because the delegate seldom needs the exact value type. ## What it carries - **`name: String`** — the source name of the property. By far the most used member. - **`returnType: KType`** — the declared type. - **`annotations`**, **`visibility`**, **`isConst`**, **`isLateinit`**, and the broader `KCallable` surface. The value passed is the property reference for that exact declaration site, so a delegate shared across several properties can tell them apart via `property.name`. ## Canonical use: map-backed delegate The standard library lets a `Map` act as a delegate by defining an extension `getValue` that looks up `property.name`: ```kotlin class User(map: Map<String, Any?>) { val name: String by map val age: Int by map } val u = User(mapOf("name" to "Ada", "age" to 36)) println(u.name) // map.getValue(u, ::name) -> map["name"] -> "Ada" println(u.age) // map["age"] -> 36 ``` Here both properties share one `Map` delegate; the `property.name` ("name", "age") selects the entry. With a `MutableMap`, the matching `setValue` writes `map[property.name] = value`, so `var` properties become writable. ## Cost These property references are lightweight synthetic objects emitted by the compiler per access site — not a runtime reflective enumeration of the class. So using `property.name` is cheap. ## A custom example ```kotlin class Prefixed(private val prefix: String) { operator fun getValue(thisRef: Any?, property: KProperty<*>) = "$prefix.${property.name}" } val host by Prefixed("db") // "db.host" val port by Prefixed("db") // "db.port" ``` One delegate, two outputs, distinguished purely by `property.name`.

  • Which Map member does the stdlib delegate use as the key?
    property.name — the declared property's name string.
  • Does using property.name trigger a heavy reflection scan?
    No. The compiler emits a lightweight property reference per access site; reading .name is cheap.

saying these in an interview costs you the question

  • Claiming KProperty gives you the current value (it describes the property, not its value)
  • Thinking each access does a full reflective class scan
  • Saying the map delegate keys by property type instead of name
  • Not knowing property.name is what disambiguates shared delegates

context