Kotlin Object Declarations — Singleton, Data Objects, and More

This article covers everything you need to know about Kotlin object declarations.

Michal Ankiersztajn
Stackademic

--

Learn how to declare objects in Kotlin. The most common use case for them is the Singleton:

1. Singleton

Frequently, you'll want your objects to be singletons. Kotlin makes the creation of these Singletons easier than any other language with sugar syntax object.

object Singleton {
fun doSomething() {...}
}

That's all you need to do to create a Singleton in Kotlin. You can access its reference by its name:

fun main() {
Singleton.doSomething()
}

There are a couple of essential things to keep in mind when using object keyword:

Lazy initialization of object Singleton
  • Object is initialized lazily, meaning when it's accessed for the first time.
  • Initialization is Thread Safe.
  • They're kept in the memory as long as the application.
  • Objects can have supertypes, for example:
object Nose : BodyPart {
override fun move() {...}
}

interface BodyPart {
fun move()
}

Nose is a Singleton that implements BodyPart because we can have only 1 Nose.

2. Data Object

data object Singleton

Just like there are data classes, there are data objects as well. Adding the data keyword tells the compiler to do the following:

  • Make toString()return the name of the object. Normally, it would return the object name + its hash, for example, Singleton@8a45s331
  • Generate equals() and hashCode() . Be careful here, as you'll not be able to override the generated code when using object
  • equals ensures that all objects of your object type will be equal. A third-party library may create a secondary Singleton using Reflection. Always use == it to compare it structurally and never === to compare it by reference.

3. Sealed hierarchies

Data objects are beneficial when you're working with sealed classes or sealed interfaces because they maintain symmetry when used with data classes.

sealed class FileResult {
data class Image(val bytes: ByteArray) : FileResult()
data class Text(val text: String) : FileResult()
data object Empty : FileResult()
}

They’re very useful when the result is static and always the same.

Thanks for reading. I hope you've learned something new! :)

Based on:

Stackademic 🎓

Thank you for reading until the end. Before you go:

--

--