Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

An object expression in Kotlin is an expression that instantiates an anonymous class at runtime. Unlike object declarations, which define lazy singletons, an object expression evaluates immediately upon execution and generates a distinct, non-singleton instance each time it is evaluated.

Syntax

The object keyword is used to define the anonymous class. It can inherit from classes, implement interfaces, or be declared without any supertypes. Without a Supertype:
val anonymousObject = object {
    val property: String = "Value"
    fun method() = "Action"
}
Inheriting from a Class and Implementing Interfaces: If the anonymous class requires a supertype, the type is specified after a colon. Constructor parameters for the superclass must be passed directly. If an anonymous object has multiple supertypes and is exposed as a non-private declaration, the Kotlin compiler requires an explicit type declaration to resolve which supertype is exposed.
open class BaseClass(val id: Int)
interface BaseInterface

// Explicit type declaration is required here
val complexObject: BaseClass = object : BaseClass(42), BaseInterface {
    override fun toString(): String {
        return "Anonymous instance with id: $id"
    }
}

Lexical Scope and Closures

Object expressions can access and mutate variables from their enclosing lexical scope. Unlike Java, Kotlin does not require captured variables to be final or effectively final.
fun executeWithState() {
    var executionCount = 0
    
    val statefulObject = object {
        fun track() {
            executionCount++ // Mutating the captured variable directly
        }
    }
    
    statefulObject.track()
}

Type System Implications

The Kotlin compiler handles the type of an anonymous object differently depending on its visibility and scope. Local and Private Scope: When an object expression is assigned to a local variable or a private property/function, the compiler retains the anonymous type. Any custom properties or functions defined exclusively inside the object remain accessible.
class Container {
    // Private visibility retains the anonymous type
    private val privateObj = object {
        val customProperty = "Accessible"
    }

    fun access() {
        println(privateObj.customProperty) // Valid compilation
    }
}
Public, Protected, and Internal Scope: When an object expression is returned from a public, protected, or internal function, or assigned to a property with one of these visibilities, the compiler degrades the type to the explicitly declared supertype. If no supertype is declared, the type resolves to Any. Members specific to the anonymous object become inaccessible to the outside scope.
class PublicContainer {
    // Public visibility degrades type to 'Any'
    val publicObj = object {
        val customProperty = "Inaccessible"
    }

    // Internal visibility degrades type to 'BaseInterface'
    internal val typedObj = object : BaseInterface {
        val customProperty = "Inaccessible"
    }

    fun access() {
        // publicObj.customProperty // Compilation error: Unresolved reference
        // typedObj.customProperty  // Compilation error: Unresolved reference
    }
}

Memory and Compilation

At the bytecode level, the Kotlin compiler generates a standard JVM anonymous inner class (e.g., EnclosingClass$1.class) for each object expression. Because a new instance is allocated on the heap every time the expression is evaluated, placing object expressions inside loops or frequently called functions incurs standard object allocation overhead.
Master Kotlin with Deep Grasping Methodology!Learn More