Objects and Companion Objects
|
This section documents Kotlin 2.4.x on the JVM, as published at kotlinlang.org, which is the reference these pages are written and verified against. This content was generated with the assistance of AI and should be verified against kotlinlang.org before being relied on in production. This section’s bibliography lists the reference material consulted while preparing these pages. |
The object keyword covers three related but distinct jobs Java splits across the singleton pattern, static
members, and anonymous inner classes.
object Declarations (Singletons)
object declares a class with exactly one instance, created lazily on first access — Kotlin’s built-in
answer to the singleton pattern, with no separate getInstance()/double-checked-locking boilerplate:
object AppConfig {
var environment: String = "production"
fun describe() = "running in $environment"
}
AppConfig.environment = "staging"
println(AppConfig.describe()) // "running in staging" -- same instance everywhere it's referenced
AppConfig can implement interfaces and extend classes exactly like an ordinary class — it just cannot declare
its own constructor, because there is only ever the one, compiler-managed instance.
Companion Objects
A companion object is a singleton object scoped to a class, replacing Java’s static members — Kotlin has
no static keyword at all:
class User private constructor(val id: Int, val name: String) {
companion object {
private var nextId = 1
fun create(name: String): User = User(nextId++, name) // factory function
}
}
val ada = User.create("Ada") // called as if "create" were static, via the class name directly
A companion object is a real object (it can implement an interface, e.g. a shared Factory<User> contract
across several classes) — it just happens to be reached through the enclosing class’s name rather than a
variable of its own. Only one companion object is allowed per class, and it may optionally be named
(companion object Factory { … }), though User.create(…) works identically either way.
Object Expressions (Anonymous Classes)
An object : SomeType { … } expression creates a one-off, unnamed instance of an interface or class — Kotlin’s equivalent of Java’s anonymous inner class, most often used where a lambda is not expressive enough
(an interface with more than one abstract method):
interface ClickListener {
fun onClick()
fun onLongClick()
}
fun registerListener(listener: ClickListener) { /* ... */ }
registerListener(object : ClickListener {
override fun onClick() = println("clicked")
override fun onLongClick() = println("long-clicked")
})
An object expression, unlike an object declaration, is not a singleton — a new instance is created every
time the expression is evaluated — and, like a Java anonymous class, it can capture and even mutate variables
from its enclosing scope.
See Also
-
Classes and Objects — ordinary class declarations that
object/companion objectbuild on. -
Lambdas and Higher-Order Functions — when a lambda is enough and an object expression is not needed.
-
Sealed Classes and Enums —
objectas the no-data variant of a sealed hierarchy.