Skip to main content

Objects and companion objects

Object declaration: one shared instance​

object AppClock {
fun nowMillis(): Long = System.currentTimeMillis()
}

The object is created lazily on first access and provides one instance in that class loader.

class UserId private constructor(val value: Long) {
companion object {
fun parse(raw: String): UserId? = raw.toLongOrNull()?.let(::UserId)
}
}

Call it as UserId.parse("42"). A companion is an object associated with the class; it is not a Java static block, although JVM annotations can expose static-looking methods to Java.

Object expression: anonymous implementation​

interface ClickListener { fun onClick(id: Long) }

val listener = object : ClickListener {
override fun onClick(id: Long) = println("Clicked $id")
}
Open in Kotlin Playground
Expected: Clicked 42.

Data object​

sealed interface LoadState {
data object Loading : LoadState
}

data object gives a singleton useful generated toString and singleton-friendly equality behavior, making it suitable for no-data states.

✕ Global mutable singleton state

object Session { var token: String? = null }

✓ Inject an owned state holder

class SessionStore(private val storage: TokenStorage) {
fun token(): String? = storage.read()
}

Global mutable objects make tests, concurrency, reset behavior, and process recreation harder to reason about.

Interview-ready answer

An object declaration creates one shared instance, a companion object holds class-related factories or constants, and an object expression creates an anonymous instance. Avoid using objects as uncontrolled global mutable state.