skip to content

What does an `object` declaration create in Kotlin, and how is it different from a regular `class`?

level: juniorimportance: must knowfreq 80%

answer

  1. object = type + single instance in one keyword
  2. No constructor, no constructor params
  3. Reference by name: Name.member
  4. Replaces private-ctor + getInstance Java idiom
  5. Can implement interfaces / extend a class

basics

~10 s

An object declaration creates a singleton: exactly one instance that Kotlin makes for you. You never call a constructor. You use it by its name, like Counter.next().

solid answer

~40 s

An `object` declaration defines a class and its single instance at the same time. The compiler guarantees exactly one instance exists for the whole program. Unlike a `class`, you cannot write a constructor or call `new`/invoke it to make more instances — you reference it directly by name (`Logger.log(...)`). It can have properties, functions, `init` blocks, implement interfaces, and extend a class. It is created lazily: the instance is initialized on first access, and that initialization is thread-safe because Kotlin compiles it to a `static final` field initialized in a static initializer. This is the idiomatic replacement for the hand-written Java singleton (private constructor + static getInstance).

code

kotlin · 9 lines
kotlin
object Registry {
    private val items = mutableListOf<String>()
    fun add(item: String) { items += item }
    fun all(): List<String> = items.toList()
}

Registry.add("a")
Registry.add("b")
println(Registry.all()) // [a, b]

go deeper

for a junior

Knows object = singleton, accessed by name, no constructor call.

for a middle

Explains it can implement interfaces/extend a class and has no constructor params; maps it to the Java idiom.

for a senior

Adds the compiled INSTANCE field and Java interop (@JvmStatic), plus init-block configuration.

for a principal

Discusses when a singleton object is appropriate vs. injectable dependency, and testability trade-offs.

## What `object` declares An **object declaration** combines two things in one keyword: it *defines a type* and *creates the single instance of that type*. It is Kotlin's built-in **singleton** — a class guaranteed to have exactly one instance. ```kotlin object AppConfig { val version = "1.0" fun describe() = "KataJob v$version" } // Usage — reference by name, no constructor call: val v = AppConfig.version println(AppConfig.describe()) ``` ## How it differs from a `class` - A `class` is a blueprint; you create instances with a constructor (`val c = Counter()`). An `object` *is* the instance — there is no constructor and no way to make a second one. - An `object` **cannot have a primary or secondary constructor**, so it can't take constructor parameters. (It can still have an `init` block.) - You access members through the object's name: `AppConfig.version`. The name resolves to the single instance. ## What it can contain An object can have: - properties and functions, - an `init { }` block for setup, - it can **implement interfaces** and **extend one open class**. ```kotlin interface Clock { fun now(): Long } object SystemClock : Clock { override fun now() = System.currentTimeMillis() } ``` ## Replacing the Java singleton idiom In Java you wrote: a `private` constructor, a `private static` field, and a `public static getInstance()`. In Kotlin that whole pattern collapses into `object Name { ... }`. The compiler generates a `public static final INSTANCE` field on the class and initializes it once, so you get correctness for free. ## Key keywords/APIs - `object` — the declaration keyword. - From Java you reach a Kotlin object via its `INSTANCE` field (`AppConfig.INSTANCE`). - `@JvmStatic` on members exposes them as true static members to Java callers (interop nicety, not required in Kotlin).

  • Can an object declaration take constructor parameters?
    No. It has no constructor, so no parameters. Configure it via an `init` block or by reading from external sources/properties.
  • How do you call an object's member from Java?
    Through the generated `INSTANCE` field: `AppConfig.INSTANCE.describe()`, or add `@JvmStatic` to call it statically.

A class is a cookie cutter; an object is the one cookie that already exists — there's only ever that one.

saying these in an interview costs you the question

  • Saying you call a constructor or `new` to use an object
  • Claiming an object can take constructor parameters
  • Confusing `object` declaration with object expression (anonymous object)
  • Thinking you must write getInstance yourself

context