Skip to main content
An object declaration in Kotlin is a language-level construct that simultaneously defines a class and creates a single, thread-safe instance of it, natively implementing the Singleton design pattern. Because the declaration creates the instance directly, you access its members using the object’s name rather than instantiating it via a constructor call.

Syntax and Structure

An object declaration is defined using the object keyword followed by a name. It can contain properties, functions, and init blocks.

Technical Characteristics

1. Constructor Restrictions Object declarations cannot have primary or secondary constructors. Because the instantiation is handled automatically by the Kotlin compiler, passing parameters during creation is not supported. Any startup logic must be placed within an init block. 2. Scope Restrictions Object declarations cannot be local (i.e., they cannot be declared directly inside a function). If a developer needs an anonymous or local object, they must use an object expression instead. 3. Lazy Initialization and Thread Safety The initialization of an object declaration is lazy. The instance is created only when it is accessed for the first time. The Kotlin compiler guarantees thread-safe initialization by leveraging the JVM’s class initialization locks under the hood (translating the object to a Java class with a static final instance). 4. Inheritance Object declarations can inherit from open classes and implement interfaces. When extending a class, the object must provide the required constructor parameters to the superclass directly in the declaration.

Companion Objects

An object declaration placed inside a class or interface can be marked with the companion keyword. This binds the object’s lifecycle and access to the enclosing type itself, providing mechanics similar to static members in Java.
Note: The name of the companion object (e.g., Factory) is optional. If omitted, it defaults to Companion.

Data Objects

Kotlin 1.9.0 introduced the data object declaration. While a standard object uses default reference-based equality and a memory-address-based toString() representation, a data object instructs the compiler to generate symmetric toString(), equals(), and hashCode() implementations based on the object’s name.
Tired of Poor Kotlin Skills? Fix That With Deep Grasping!Learn More