In this tutorial, we’ll look at how Kotlin deals with Singleton Pattern and static properties. We will learn how to create Kotlin Singleton class and what is companion object.
Table of Contents
Kotlin Singleton Class
A Singleton is a software design pattern that guarantees a class has one instance only and a global point of access to it is provided by that class.
Singleton Pattern ensures that only one instance would be created and it would act as a single point of access thereby ensuring thread safety. Following is the generic way to create a Singleton class in Java.
public class Singleton {
private static Singleton instance = null;
private Singleton(){
}
private synchronized static void createInstance() {
if (instance == null) {
instance = new Singleton();
}
}
public static Singleton getInstance() {
if (instance == null) createInstance();
return instance;
}
}
The synchronized
keyword ensures that there are no thread interferences when creating the instance.
The Kotlin equivalent of the above code is given below.
object Singleton
Yes, that’s it for creating a singleton class in Kotlin.
Kotlin object Declaration
- Kotlin’s representation of a Singleton class requires the
object
keyword only. - Hence a Singleton class in Kotlin can be defined without the use of a class.
- An
object
class can contain properties, functions and theinit
method. - The constructor method is NOT allowed.
- A singleton object can be defined inside a class. It cannot be defined inside an inner class.
- An object cannot be instantiated in the way a class is instantiated.
- An object gets instantiated when it is used for the first time.
Let’s see a basic implementation of an object
in Kotlin.
object Singleton
fun main(args: Array<String>) {
print(Singleton.javaClass)
}
//Following is printed in the console.
//class Singleton
The javaClass
is auto-generated by the singleton class and prints the equivalent name for the Java class name.
Let’s add a function and properties in the object
singleton class.
object Singleton
{
init {
println("Singleton class invoked.")
}
var name = "Kotlin Objects"
fun printName()
{
println(name)
}
}
fun main(args: Array<String>) {
Singleton.printName()
Singleton.name = "KK"
var a = A()
}
class A {
init {
println("Class init method. Singleton name property : ${Singleton.name}")
Singleton.printName()
}
}
//Following is printed in the console.
//Singleton class invoked.
//Kotlin Objects
//Class init method. Singleton name property : KK
//KK
In the above code, the changes in the object class are reflected when the class A
is instantiated.
Object initialization is similar to lazy initialization of kotlin properties. In the below code, object
isn’t initialized since it isn’t used.
class A {
object Singleton
{
init {
println("Singleton class invoked.")
}
var name = "Kotlin Objects"
fun printName()
{
println(name)
}
}
init {
println("Class init method. Singleton name property")
}
}
//Console:
//Class init method
Objects have much more to use than just being a Singleton class.
Kotlin Object Expressions
Objects in Kotlin, can be used as class variants. An object can extend a class, implement an interface.
Let’s look at extending a class in the object to create a variant.
fun main(args: Array<String>) {
var a = A()
Singleton.printName()
}
open class A {
open fun printName() {
print("This is class A")
}
init {
println("Class init method.")
}
}
object Singleton : A() {
init {
println("Singleton class invoked.")
}
var name = "Kotlin Objects"
override fun printName() {
println(name)
}
}
//Console Output:
//Class init method.
//Class init method.
//Singleton class invoked.
//Kotlin Objects
We’ve defined the class and function printName()
as open
since they would be subclassed and overridden respectively.
Unarguably, the init
function of the class is called twice. Thus we are able to able to create an anonymous class in Kotlin using the above method.
Objects can have superclasses.
Kotlin Companion Object
- Kotlin doesn’t have
static
keyword. So how do we set static variables and methods? companion object
is the answer. It is equivalent tostatic
objects in Java.- A
companion object
is common to all instances of the classes. It can access all members of the class too, including the private constructors. - A companion object is initialized when the class is instantiated.
- A companion object CANNOT be declared outside the class.
Let’s look at a simple example of kotlin companion object.
fun main(args: Array<String>) {
var a = A.name
A.name = "Kotlin Tutorials"
A.printName() //prints Kotlin Tutorials
}
class A {
companion object Singleton
{
init {
println("Singleton class invoked.")
}
var name = "Kotlin Objects"
fun printName()
{
println(name)
}
}
init {
println("Class init method.")
}
}
Members of the companion object are called by using the class name as the qualifier.
We can omit the companion object name too. In that case Companion
name can be used to call the Singleton object.
fun main(args: Array<String>) {
A.Companion
A.Companion.name = "Kotlin Tutorials"
A.printName() //prints Kotlin Tutorials
}
class A {
companion object
{
init {
println("Singleton class invoked.")
}
var name = "Kotlin Objects"
fun printName()
{
println(name)
}
}
init {
println("Class init method.")
}
}
Note: object
isn’t instantiated until it is called. companion object
is instantiated as soon as the class is as shown in the below code.
fun main(args: Array<String>) {
var a = A()
}
class A {
companion object SingletonB {
init {
println("SingletonB class invoked.")
}
}
object SingletonA {
init {
println("SingletonA class invoked.")
}
}
init {
println("Class init method.")
}
}
//Following is printed in the console.
//SingletonB class invoked.
//Class init method.
Notice that the init of object
wasn’t called. This brings an end to kotlin singleton and companion object example tutorial.
Reference:Kotlin Docs
How singleton reference can be get using method in kotlin like singleton object reference in java