What does `KClass.objectInstance` return, and how does it behave for objects vs regular classes?
answer
- objectInstance returns the singleton, else null
- non-object class -> null, not an exception
- great with sealedSubclasses.mapNotNull
- needs kotlin-reflect at runtime
- reading it initializes the object (side effect)
basics
~10 sobjectInstance gives you the single shared instance of a Kotlin object (a singleton). If the KClass is for an object declaration it returns that instance; for an ordinary class it returns null.
solid answer
~40 s`KClass<T>.objectInstance` is a nullable property (`T?`) that returns the singleton instance when the `KClass` represents a Kotlin `object` declaration (a `companion object`, a named `object Foo`, or an anonymous-but-named object), and `null` otherwise. It lets reflective code resolve a singleton without knowing its name: `MyService::class.objectInstance` returns the lone `MyService` instance, while `String::class.objectInstance` is `null` because `String` is a regular class. This is invaluable when, for example, you scan `sealedSubclasses` and need the actual instances of the object-typed variants. Accessing `objectInstance` requires the `kotlin-reflect` dependency at runtime — it is part of the full reflection surface, not the stdlib stub. It triggers class initialization (the object is created lazily on first access of the underlying JVM `INSTANCE` field).
code
kotlin · 8 linessealed interface State
object Idle : State
object Running : State
data class Error(val msg: String) : State
fun objectStates(): List<State> =
State::class.sealedSubclasses.mapNotNull { it.objectInstance }
// [Idle, Running]go deeper
Knows object is a singleton and that objectInstance retrieves it.
Knows it returns null for non-objects and pairs it with sealedSubclasses.mapNotNull.
Aware of the kotlin-reflect requirement and the class-initialization side effect.
Designs serialization/registry layers that branch on object vs class variants without leaking reflection cost into hot paths.
## The property `objectInstance: T?` is a member of `KClass<T>`. It answers: *if this class is a singleton `object`, give me that instance*. - For an `object` declaration -> returns the singleton. - For a normal `class`, `interface`, `enum`, etc. -> returns `null`. ## What counts as an object Kotlin's `object` keyword declares a singleton — a class with exactly one instance, created lazily and held in a synthetic JVM `INSTANCE` field. Named objects (`object Config`), `companion object`s, and object expressions assigned to a declaration all qualify. ```kotlin object Config { val env = "prod" } class Service fun main() { println(Config::class.objectInstance) // Config@... (the singleton) println(Service::class.objectInstance) // null } ``` ## Why it matters: pairing with sealed hierarchies A very common pattern is a sealed hierarchy where some variants are objects (no state) and some are classes (with data). Reflection lets you turn the type list into usable instances: ```kotlin sealed interface Event object Started : Event object Stopped : Event data class Failed(val cause: String) : Event fun singletonEvents(): List<Event> = Event::class.sealedSubclasses.mapNotNull { it.objectInstance } // -> [Started, Stopped] (Failed has no objectInstance -> filtered out) ``` `mapNotNull` discards the `null`s coming from the non-object subclass `Failed`. ## Runtime requirements `objectInstance` is part of the *full* reflection API and needs the `org.jetbrains.kotlin:kotlin-reflect` artifact on the classpath; the lightweight stdlib `KClass` (used for `simpleName`/`qualifiedName`/identity) does not implement it. Calling it on a non-object simply returns `null` — it does not throw. ## Initialization side effect Reading `objectInstance` forces the JVM to load and initialize the object class, running its property initializers and `init` block. So it is not purely a metadata read — it can have observable side effects. ## Contrast - `objectInstance` -> the instance (or null). - `isCompanion` / `isData` / `isSealed` etc. -> boolean class-kind flags. - Calling a constructor reflectively is a different path entirely (and would fail for an object, which has no public constructor).
- What does `objectInstance` return for a regular `class`?`null`; it never throws for non-objects.
- Does reading `objectInstance` have side effects?Yes — it forces class initialization of the object, running its init block and field initializers.
saying these in an interview costs you the question
- Saying it throws for non-object classes (it returns null)
- Confusing `objectInstance` with reflectively calling a constructor
- Forgetting it needs kotlin-reflect at runtime
- Assuming it works on enum entries the same way (use enum's own values instead)