Show how constructor references (::ClassName) and mutable-property references work, including using a property reference to both read and write a field reflectively.
answer
- ::Class = constructor as factory function
- val ref -> KProperty (get only)
- var ref -> KMutableProperty (get + set)
- Unbound = KProperty1 (receiver), bound = KProperty0
- get/set need kotlin-reflect; ::Class as factory doesn't
basics
~10 s::ClassName references a constructor and acts like a factory function. A property reference to a var lets you read it with get and change it with set, because it is a KMutableProperty.
solid answer
~40 sA constructor reference ::User is a callable whose function type matches the constructor — (String) -> User for a single-arg constructor — so you can do names.map(::User) as a factory. A property reference to a val is a KProperty (read-only: has get); a reference to a var is a KMutableProperty, adding set. Unbound, they are KProperty1/KMutableProperty1 and take the receiver: User::email.get(user) reads, User::name.set(user, "Ada") writes. Bound (user::name) they are KProperty0/KMutableProperty0 with no receiver: user::name.set("Ada"). Constructor references also satisfy functional interfaces, which is why they're handy in builders and DI factories. All of get/set go through reflection, so the introspecting forms need kotlin-reflect at runtime, though using ::User purely as a factory function does not.
code
kotlin · 9 linesclass Point(var x: Int, var y: Int)
val factory: (Int, Int) -> Point = ::Point
val p = factory(1, 2)
val xRef = Point::x // KMutableProperty1<Point, Int>
println(xRef.get(p)) // 1
xRef.set(p, 99) // reflective write
println(p.x) // 99go deeper
Can use ::ClassName as a factory in map and read a property via a bound reference.
Knows the val->KProperty / var->KMutableProperty distinction and uses get/set correctly for bound and unbound forms.
Explains the full KProperty0/1 + KMutableProperty0/1 matrix and the kotlin-reflect boundary, and warns about reflective get/set cost.
Designs generic binding/copy utilities around property references while controlling the reflection dependency and performance footprint.
## Constructor references Prefix a class name with `::` to reference its **constructor** as a function value. The reference's type is the constructor's signature returning the class: ```kotlin class User(val name: String) val make: (String) -> User = ::User val users = listOf("Ada", "Linus").map(::User) // factory via reference ``` This works with only the stdlib when used as a plain function. Overloaded constructors resolve by expected type, like any overloaded reference. ## Property references and the KProperty hierarchy A property reference's reflective type depends on **mutability** and **bound/unbound**: | Form | val (read-only) | var (mutable) | |------|-----------------|----------------| | Unbound `Class::p` | `KProperty1<T, V>` | `KMutableProperty1<T, V>` | | Bound `obj::p` | `KProperty0<V>` | `KMutableProperty0<V>` | - A **`KProperty`** exposes a `getter` and `get(...)`. - A **`KMutableProperty`** (only for `var`) additionally exposes a `setter` and `set(...)`. ```kotlin class Account(var balance: Int) val acc = Account(100) // Unbound: receiver passed explicitly val balProp = Account::balance // KMutableProperty1<Account, Int> println(balProp.get(acc)) // 100 balProp.set(acc, 250) // write via reflection // Bound: receiver fixed val bound = acc::balance // KMutableProperty0<Int> bound.set(500) println(bound.get()) // 500 ``` If `balance` were a `val`, `Account::balance` would be a `KProperty1` with **no** `set`, and the call wouldn't compile. ## Why this matters - Constructor refs make clean **factories** (`map(::User)`, DI providers). - Mutable property refs power **generic copy/validation/binding** code that reads or assigns fields by reference rather than hardcoded names. - The **dependency rule** still holds: `::User` as a function is stdlib-only; `get`/`set`/inspecting the property is **kotlin-reflect**. ## Gotcha `get`/`set` are reflective calls — slower than direct access and may bypass nothing about visibility unless you opt in. Prefer direct access in hot paths; reserve property-reference get/set for genuinely generic code.
- What's the type of a bound reference to a var property, e.g. point::x?KMutableProperty0<Int> — bound drops the receiver, and var makes it mutable, so it has get() and set(value).
- Can you call .set on a reference to a val property?No. A val gives a KProperty (read-only); set doesn't exist on it, so the code won't compile.
saying these in an interview costs you the question
- Thinking a val property reference can write via set
- Confusing constructor reference with calling the constructor
- Not knowing KMutableProperty adds the setter over KProperty
- Believing ::User as a factory requires kotlin-reflect
- Mixing up KProperty0 (bound) and KProperty1 (unbound)