What you'll learn
Kotlin has no static keyword. Instead it offers something cleaner: the object declaration for singletons, and the companion object for class-level members and factories. This module covers all the ways to use object.
By the end you'll be able to:
- Create singletons with
object - Make one-off anonymous objects with object expressions
- Add class-level members and factory methods with
companion object
object declarations (singletons)
Declaring object Name creates a singleton — a class with exactly one instance, created lazily and thread-safely the first time it's used. You access its members directly on the name, never instantiating it. It's perfect for a shared registry, configuration, or manager:
object Database { // a SINGLETON — only ever one instance
val connections = mutableListOf<String>()
fun connect(name: String) {
connections.add(name)
println("Connected: $name")
}
}
Database.connect("primary") // access directly — no instantiation
Database.connect("replica")
println(Database.connections.size) // 2Tip
getInstance(), no thread-safety code. Kotlin handles all of it. Use an object whenever you genuinely need exactly one instance.Object expressions
An object expression creates an anonymous object on the spot — often to implement an interface for a single use, like an event listener. It's Kotlin's equivalent of a Java anonymous class:
interface ClickListener {
fun onClick()
}
// an object EXPRESSION creates a one-off anonymous object
val listener = object : ClickListener {
override fun onClick() = println("Clicked!")
}
listener.onClick()Note
ClickListener), you can usually pass a lambda instead — even cleaner. Object expressions are for when you need to override multiple methods or hold state.Companion objects
Since Kotlin has no static, how do you attach members to a class rather than its instances — like factory methods or constants? A companion object: a single object tied to the class, whose members you call on the class name itself:
class User private constructor(val name: String) {
companion object {
fun create(name: String): User { // a factory method
println("Creating user...")
return User(name)
}
}
}
val u = User.create("Sara") // called on the CLASS, like a static method
println(u.name)Key idea
static members. It's especially loved for factory methods — combined with a private constructor, you control exactly how instances are created (validating input, returning cached instances, choosing a subclass).Recap & quick check
Key takeaways
- Kotlin has no 'static'; 'object' and 'companion object' fill the gap.
- object Name creates a lazy, thread-safe singleton accessed directly on the name.
- Object expressions create one-off anonymous objects (like Java anonymous classes).
- A companion object attaches class-level members (constants, factory methods) called on the class name.
- Companion + private constructor is the idiomatic way to write factory methods.
Quick check
1. What does an 'object' declaration create?
2. Kotlin has no 'static' keyword. What replaces class-level members?
3. How do you access a companion object's function?
4. What is an object expression used for?
5. What's the idiomatic way to write a factory method in Kotlin?
Great — you've mastered Kotlin's take on statics and singletons. Next up: Module 18 — Sealed Classes & Enums.