← All courses

Objects, Companions & Singletons

🗓 May 31, 2026 ⏱ 2 min read

The object keyword: instant singletons

Sometimes you want exactly one instance of something for the whole app — a configuration holder, a logger. In Kotlin, object creates a singleton in one line; the language guarantees only one instance exists.

object AppConfig {
    const val VERSION = "1.0.0"
    var darkMode = false
    fun toggleTheme() { darkMode = !darkMode }
}

// use it directly — no 'new'
println(AppConfig.VERSION)
AppConfig.toggleTheme()

Companion objects: “static” members

Kotlin has no static keyword. Instead, members that belong to the class itself (not an instance) go in a companion object — a great place for factory methods and constants.

class User private constructor(val name: String) {
    companion object {
        const val MAX_NAME_LENGTH = 30

        fun create(name: String): User {
            require(name.length <= MAX_NAME_LENGTH)
            return User(name)
        }
    }
}

val u = User.create("Anand")     // factory method
println(User.MAX_NAME_LENGTH)

Here the constructor is private, so the only way to build a User is through the controlled create factory — a common, clean pattern.

Anonymous objects

You can also create a one-off object on the spot, often to implement an interface (like a click listener):

val listener = object : Clickable {
    override fun onClick() = println("clicked once")
}

object vs class

  • class — a blueprint you instantiate many times.
  • object — a single, ready-made instance (singleton).
  • companion object — class-level members shared by all instances.

Common mistakes

  • Storing lots of changing state in a global object — singletons with mutable state can cause hard-to-trace bugs. In Android, prefer dependency injection.
  • Using a companion object for things that should be top-level functions.
Summary: object gives you a one-line singleton; companion object replaces Java’s static members and is perfect for factory methods and constants.