To create thread-safe Singletons in Kotlin, we can rely on object declarations, as we discovered in Chapter 5, Modeling Real-World Data. To create a Kotlin equivalent implementation of our ThreadSafeSingleton example from the previous section, we can write the following Kotlin code:
object ThreadSafeSingleton
With this single line, we can now access ThreadSafeSingleton from anywhere in our code base in a thread-safe manner. Adding the object keyword rather than class ensures that the compiler will generate bytecode that enforces the Singleton pattern for us.
We can now add a property to our ThreadSafeSingleton object to demonstrate how to access properties of an object declaration. Consider the following code snippet:
object ThreadSafeSingleton {
const val platform = "JVM"
}
To reference the newly added platform property, we simply reference the property name preceded by the object declaration name, shown as follows:
fun main() {
ThreadSafeSingleton.platform
}
By leveraging object declarations, we can quite easily implement the Singleton pattern using Kotlin. This is a common pattern when defining sealed class hierarchies and defining types that only need to exist in memory a single time.
Using object expressions to enforce single instances of classes that don't require configuration is convenient, but what about classes that do require a constructor? We'll explore this use case in the next section.