kotlinbeginner

Object Declarations — Singletons and Anonymous

Use object declarations for singletons, anonymous objects, and object expressions in Kotlin.

kotlin
// Singleton object
object AppRegistry {
    private val services = mutableMapOf<String, Any>()

    fun register(name: String, service: Any) {
        services[name] = service
    }

    @Suppress("UNCHECKED_CAST")
    fun <T> get(name: String): T = services[name] as T

    fun list(): Set<String> = services.keys
}

// Singleton with initialization
object DatabaseConfig {
    val url: String
    val maxConnections: Int

    init {
        url = System.getenv("DB_URL") ?: "jdbc:h2:mem:test"
        maxConnections = System.getenv("DB_MAX_CONN")?.toIntOrNull() ?: 10
        println("DatabaseConfig initialized: $url")
    }

    fun info() = "$url (max: $maxConnections)"
}

// Object implementing interface
interface Comparator<T> {
    fun compare(a: T, b: T): Int
}

object StringLengthComparator : Comparator<String> {
    override fun compare(a: String, b: String) = a.length - b.length
}

// Anonymous object
interface EventListener {
    fun onEvent(event: String)
    fun onError(error: String)
}

class EventEmitter {
    private val listeners = mutableListOf<EventListener>()

    fun addListener(listener: EventListener) { listeners.add(listener) }

    fun emit(event: String) {
        listeners.forEach { it.onEvent(event) }
    }
}

// Enum-like object hierarchy
sealed class LogLevel(val priority: Int, val label: String) {
    object DEBUG : LogLevel(0, "DEBUG")
    object INFO : LogLevel(1, "INFO")
    object WARN : LogLevel(2, "WARN")
    object ERROR : LogLevel(3, "ERROR")

    companion object {
        fun fromString(s: String): LogLevel = when (s.uppercase()) {
            "DEBUG" -> DEBUG
            "INFO" -> INFO
            "WARN" -> WARN
            "ERROR" -> ERROR
            else -> INFO
        }
    }
}

fun main() {
    // Singleton
    AppRegistry.register("db", DatabaseConfig)
    AppRegistry.register("logger", "ConsoleLogger")
    println("Services: ${AppRegistry.list()}")
    println("DB: ${AppRegistry.get<Any>("db")}")

    // Object reference
    println("DB info: ${DatabaseConfig.info()}")

    // Anonymous object
    val emitter = EventEmitter()
    emitter.addListener(object : EventListener {
        override fun onEvent(event: String) = println("Event: $event")
        override fun onError(error: String) = println("Error: $error")
    })
    emitter.emit("user.login")

    // LogLevel
    val level = LogLevel.fromString("warn")
    println("Level: ${level.label} (${level.priority})")

    // Object comparison (reference equality works for singletons)
    println(LogLevel.DEBUG === LogLevel.DEBUG) // true
}

Use Cases

  • Thread-safe singleton services
  • Event listener implementations
  • Application-wide configuration

Tags

Related Snippets

Similar patterns you can reuse in the same workflow.