What is a property reference like ::name or Person::name in Kotlin, and what can you do with the value you get?
answer
- :: makes a property a value, not its value
- Type::prop is KProperty1 and acts as (T) -> R
- .get / .set / .name on the reference
- var gives KMutableProperty with .set
- people.map(Person::name)
basics
~10 sIt is a value that points to a property instead of reading it. You can pass it to functions like map to read that property from many objects, for example people.map(Person::name).
solid answer
~30 sA property reference uses the :: operator to refer to a property as a first-class object instead of accessing its value. Person::name yields a KProperty1<Person, String> (a function-like object). Calling it with a Person returns that person's name, so it works as a (Person) -> String, ideal for people.map(Person::name). For a property in scope, ::count gives a KProperty0. The reference also exposes metadata: .name returns the property's name as a String, and .get(receiver) reads the value. If the property is a var, mutable reference types (KMutableProperty1) also expose .set(receiver, value).
code
kotlin · 4 linesdata class User(val email: String)
val users = listOf(User("[email protected]"), User("[email protected]"))
val emails = users.map(User::email) // [[email protected], [email protected]]
println(User::email.name) // "email"go deeper
Knows ::prop is a value and can use Person::name in map.
Names KProperty1, knows .get/.name and that var yields a mutable reference.
Distinguishes KProperty0/1, mutable vs read-only, and how it acts as a function type.
Frames it as kotlin.reflect first-class members enabling type-safe generic field access in libraries.
## What a property reference is A **property reference** is created with the **`::` (double-colon) operator** and refers to a Kotlin **property** as a first-class object you can store, pass, and call — rather than reading its current value. `Person::name` does not read a name; it produces an object representing the `name` property of `Person`. ## The type you get: KProperty The reference's type comes from the **`kotlin.reflect`** hierarchy: - `Person::name` (unbound, on a type) → **`KProperty1<Person, String>`** — a property with one receiver. It is also a function `(Person) -> String`. - `::topLevelOrLocalProp` (no receiver) → **`KProperty0<String>`** — call it with `()`. - A reference to a `var` adds a setter: **`KMutableProperty1`** / **`KMutableProperty0`**, exposing `.set(...)`. ## Why it doubles as a function `KProperty1<T, R>` implements the function type `(T) -> R` via its `invoke`/`get`, so it can be passed anywhere a lambda of that shape is expected: ```kotlin data class Person(val name: String, var age: Int) val people = listOf(Person("Ada", 36), Person("Linus", 54)) val names: List<String> = people.map(Person::name) // [Ada, Linus] // Reflection API on the same reference: val ref = Person::name println(ref.name) // "name" (metadata) println(ref.get(people[0])) // "Ada" val ageRef = Person::age // KMutableProperty1<Person, Int> ageRef.set(people[0], 99) // requires var ``` ## Key APIs - **`.get(receiver)`** — read the value. - **`.set(receiver, value)`** — write (only on `KMutableProperty*`). - **`.name`** — the property's source name as a `String`. - **`.invoke(receiver)`** / calling it like a function — same as `get`. ## Common uses - `map`, `sortedBy`, `groupBy`, `associateBy` with `Type::prop`. - Building generic, type-safe "get this field" logic without writing lambdas.
- What is the difference between Person::name and ::name?Person::name is unbound (KProperty1, needs a Person receiver). ::name refers to a property in the current scope (KProperty0), called with no receiver.
Like handing someone a labelled measuring tool ('the name field') instead of a single measurement you already took.
saying these in an interview costs you the question
- Saying Person::name reads/returns the name value immediately
- Claiming it only works inside reflection and cannot be passed to map
- Not knowing it has a usable .name or .get
- Thinking it needs an instance to be written (Person::name vs p::name)