Kotlin makes it easy to implement a singleton. If you aren't familiar with this, a singleton is an object that is only instantiated once for an application. We will explore the singleton pattern specifically in more detail in Chapter 17, Practical Design Patterns.
To quickly implement a singleton in Kotlin, we can use an object declaration that uses the object keyword to define a singleton class. In this code, SettingsManager is defined using an object declaration and is a publicly available singleton:
object SettingsManager : SettingsProvider {
val map = HashMap<String, String>()
fun printSettings() = map.forEach { println(it) }
override fun getSetting(key: String)
= map.getOrDefault(key, "default")
}
Note that object declarations can implement interfaces or extend other classes. To work with an object declared this way, we can reference the object name directly to access any properties or methods:
fun main(args: Array<String>) {
val setting = SettingsManager.getSetting("key")
}
Object declarations are created via thread-safe, lazy instantiation. This means object declarations cannot provide a constructor. Let's take a look at a basic example so we can examine the generated bytecode. We've defined the most basic object declaration we can to create SimpleSingleton:
object SimpleSingleton
Now, let's look at the generated code:
public final class SimpleSingleton {
public static final SimpleSingleton INSTANCE;
private SimpleSingleton() {
}
static {
SimpleSingleton var0 = new SimpleSingleton();
INSTANCE = var0;
}
}
We can see here that the compiler generates the standard Java singleton code that you may be used to working with. This is how we can use an object declaration without worrying about manual, thread-safe instantiation.
Object declarations mimic the static functionality available in Java. They allow us to have globally available methods and properties that are available when needed. Sometimes, however, we'd prefer to scope this functionality to some other class. For those situations, we can rely on companion objects, which we'll explore in the following section.