Compare members, functions, and declaredMemberProperties on a KClass. What does each return and how do they differ regarding inheritance?
answer
- members = all callables incl. inherited
- functions includes Any's equals/hashCode/toString
- declared* = this class only
- declaredMemberProperties → KProperty1, no inheritance/extensions
- memberProperties = declared + inherited
basics
~10 smembers lists all callable members (functions and properties), including inherited ones. functions lists functions including inherited. declaredMemberProperties lists only properties declared in that class, not inherited ones.
solid answer
~30 sThese are extension accessors from `kotlin.reflect.full`. `members: Collection<KCallable<*>>` returns **all** callables — functions and properties — declared in the class **and inherited** from supertypes (plus synthetic ones like component functions). `functions: Collection<KFunction<*>>` returns all member functions, including inherited and those from `Any` (equals, hashCode, toString). The `declared*` family is **not** inheritance-aware: `declaredMemberProperties` returns only `KProperty1`s declared in **this** class (excluding inherited and extension properties), and `declaredFunctions` only functions declared here. There are also `memberProperties` (declared + inherited, no extensions) and `memberExtensionFunctions/Properties` for member extensions. Rule of thumb: `declared*` = this class only; the non-declared accessors walk the supertype chain.
code
kotlin · 8 linesimport kotlin.reflect.full.declaredMemberProperties
import kotlin.reflect.full.memberProperties
open class Base(val id: Long)
class Item(val sku: String) : Base(1)
println(Item::class.declaredMemberProperties.map { it.name }) // [sku]
println(Item::class.memberProperties.map { it.name }) // [id, sku]go deeper
Knows declared* is this-class-only while members/functions include inherited members.
Builds the correct table and picks declaredMemberProperties vs memberProperties appropriately.
Explains extension-property exclusion, synthetic data-class members in members, and manual visibility filtering.
Discusses performance of enumerating large member sets and designing reflection scans that are inheritance- and visibility-aware.
## Where these live All three are **extension properties** on `KClass<*>` from the package `kotlin.reflect.full` (you must `import` them), backed by the `kotlin-reflect` runtime library. ## What each returns | Accessor | Element type | Includes inherited? | Functions? | Properties? | |---|---|---|---|---| | `members` | `KCallable<*>` | **Yes** | Yes | Yes | | `functions` | `KFunction<*>` | **Yes** (incl. `Any`) | Yes | No | | `declaredFunctions` | `KFunction<*>` | No | Yes | No | | `memberProperties` | `KProperty1<T, *>` | **Yes** | No | Yes | | `declaredMemberProperties` | `KProperty1<T, *>` | No | No | Yes | - **`members`** is the broadest: every callable you could invoke on an instance, declared **or** inherited, including compiler-generated members (e.g. `componentN`, `copy` on data classes). - **`functions`** includes inherited functions and the three from `kotlin.Any` (`equals`, `hashCode`, `toString`). Use `declaredFunctions` to exclude them. - **`declaredMemberProperties`** is the most common for serialization/mapping: it gives just **this** class's own non-extension properties as `KProperty1`, so you read each with the instance receiver. ## The 'declared' distinction The key axis is **inheritance**. Anything prefixed `declared` looks **only** at the class itself; the non-prefixed `member*` accessors include members inherited from supertypes. Neither `memberProperties` nor `declaredMemberProperties` includes **extension** properties — use `memberExtensionProperties` for those. ```kotlin import kotlin.reflect.full.* open class Animal(val legs: Int) class Dog(val name: String) : Animal(4) Dog::class.declaredMemberProperties.map { it.name } // [name] Dog::class.memberProperties.map { it.name } // [legs, name] Dog::class.functions.map { it.name } // ... + equals/hashCode/toString Dog::class.declaredFunctions.map { it.name } // only Dog's own functions ``` ## Practical guidance For mapping the fields a class actually defines, prefer `declaredMemberProperties`. To include the full inherited surface, use `memberProperties`/`members`. Be aware visibility filtering is your job — these return all visibilities; check `KCallable.visibility` to skip `PRIVATE`.
- Why might functions return more than you expect for a simple class?It includes inherited functions, notably equals, hashCode, and toString from kotlin.Any.
- How do you list only the properties a class itself defines?Use declaredMemberProperties (excludes inherited and extension properties).
- Do these accessors filter by visibility?No; they return all visibilities. Filter manually using KCallable.visibility.
saying these in an interview costs you the question
- Claiming declaredMemberProperties includes inherited properties
- Forgetting functions includes Any's members
- Thinking members only returns functions
- Assuming these accessors auto-skip private members