How to create a Singleton class in Kotlin

Reading Time: 3 minutes

What is Singleton Class?

First of all, let us discuss what is singleton class is. We can define a singleton class in such a way that only one instance of the class can create and we can use that instance everywhere. We can use a singleton class where we need only one instance of the class like NetworkService, DatabaseService, etc.

Generally, it is done because it takes the resource of the system to create these objects again and again. So it is better to create only once and use again and again the same object.

Properties:

  • This class have only one instance. It can be complete by providing an instance of the class, within the class. Since, outer classes and child classes should prevent to create the instance.
  • The instance of the singleton class should be globally accessible so that each class can use it.

Rules for making Singleton Class:

  • A private constructor
  • A static reference of its class
  • One static method
  • Globally accessible object reference
  • Consistency across multiple threads

Singleton example in Kotlin:

object Singleton{
    
    init {
        println("Hello Singleton!")
    }
    var variableName = "I am Var"
    fun printVarName(){
        println(variableName)
    }

}

fun main(args: Array<String>) {     
    Singleton.printVarName()
    Singleton.variableName = "New Name"
        
    var a = A()
}

class A {

    init {
        println("This is singleton method : ${Singleton.variableName}")
        Sing

For instance, In the above code, we are having one function name as printVarName() and one property name as variableName. When we initiate class A, then changes can be reflected in the object class. So the output of the following code is:

Hello Singleton!
I am Var
This is Singleton method : New Name 
New Name 

Object extending class:

fun main(args: Array<String>) {
    var a = A()
    Singleton.printVarName()
}

open class A {

    open fun printVarName() {
        print("I am in class printVarName")
    }

    init {
        println("I am in init of A")
    }
}

object Singleton : A() {

    init {
        println("Hello Singleton!")
    }

    var variableName = "I am Var"
    override fun printVarName() {
        println(variableName)
    }

Output:

I am init of AOutput: 
I am init of A
Hello Singleton!
I am var

Singleton class with Argument in Kotlin:

In the above part of the blog, we learned that we cannot create constructors in a singleton class. To do so we can do it by using init in the singleton class. But have you ever thought that what if you want to use parameterized constructors? To do so we have to find some other way.

If we especially conversation around Android, we know that in Android we by and large have to pass a context instance to init block of a singleton. We can do it by using Early initialization and Apathetic initialization. In early initialization, all the components are initialized within the Application.onCreate() utilizing the init() capacities. But this comes about in abating down the application startup by blocking the most string. So, it is for the most part exhorted to utilize the lazy initialization way. In lazy initialization, we utilize the context as a contention to a function returning the occasion of the singleton. We will accomplish this by using a SingletonHolder class. Also, to create it thread-safe, we ought to have a way of synchronization and double-checked locking.

open class SingletonHolder<out T: Any, in A>(creator: (A) -> T) {
    private var creator: ((A) -> T)? = creator
    @Volatile private var instance: T? = null

    fun getInstance(arg: A): T {
        val checkInstance = instance
        if (checkInstance != null) {The above code is the foremost effective code for double-checked locking framework and the code is by one means or another comparative to the lazy() work in Kotlin and that’s why it is called lazy initialization. So, at whatever point you need a singleton class with arguments at that point you'll be able utilize the SingletonHolder class.
            return checkInstance
        }

        return synchronized(this) {
            val checkInstanceAgain = instance
            if (checkInstanceAgain != null) {
                checkInstanceAgain
            } else {
                val created = creator!!(arg)
                instance = created
                creator = null
                created
            }
        }
    }
}

The above code is the foremost effective code for double-checked locking framework and the code is by one means or another comparative to the lazy() work in Kotlin and that’s why it is called lazy initialization. So, at whatever point you need a singleton class with arguments at that point you’ll be able to utilize the SingletonHolder class.

Conclusion:

In conclusion, in this blog, we have learned about the Singleton class, rules for making a singleton class, and also implemented it on kotlin. I will cover more topics in the further blogs. Happy learning 🙂

For more, you can refer to the kotlin documentation: https://kotlinlang.org/docs/getting-started.html#create-your-powerful-application-with-kotlin

Checkout more Kotlin Blogs here.

knoldus

Written by 

Hello! Currently, I am Software Consultant at Knoldus Inc. I have completed my B.Tech from Abdul Kalam Technical University. Right now I am focusing on JAVA Frameworks. Apart from that my hobbies are playing guitar and listening to music.