An object declaration defines a class and its only instance in one step. The instance is created lazily on first access, and that initialization is thread-safe, so Java's double-checked locking is unnecessary. It resembles a JavaScript module that exports one shared object.
object CartStore {
private val titles = mutableListOf<String>()
init { println("CartStore initialized") }
fun add(title: String) { titles += title }
val count get() = titles.size
}
data object EmptyCart
fun main() {
println("BookNest started")
CartStore.add("The Quiet Harbor")
println("Items: ${CartStore.count}, then $EmptyCart")
}BookNest started CartStore initialized Items: 1, then EmptyCart
CartStore initialized prints after BookNest started, at the first call to add. The data object prints its name, where a plain object prints something like PlainCart@6bc7c054, and it suits stateless cases such as data object Loading in a sealed hierarchy (Sealed and Enum Classes). The related object expression, object : Runnable { ... }, creates an anonymous instance each time it runs, like a JavaScript object literal. Never hold an Activity or Context in a singleton: it outlives the screen and leaks it.