1
public class Singleton {
    private static Singleton instance = null;
    private Singleton(){
    }

    public synchronized static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        doSomeInitializationIfRequired();
        return instance;
    }
}

here getInstance() method is called whenever we request for the Instance where we can add code if we want to do something when the instance is called from any where everytime.

is there some way to override instance variable get() like this with Kotlin Objects

e.g.

object SomeSingleton {
    get() = {
        doSomeInitializationIfRequired()
    }
}

I know i can write

init {
}

but that will be called only once.

6
  • Can you please explain why you need to call your doSomeInitializationIfRequired() method whenever the singleton is referenced? Maybe also tell us what you're doing in said method Commented Jun 22, 2020 at 7:49
  • So we are using Dynamic Delivery where each module is downloaded on demand, this singleton is present in base app and depends on some module to provide interface which gets initialized when its downloaded so basically whenever this singleton is referenced i want to be able to see if the module is present and initialize the interfaces if required Commented Jun 22, 2020 at 7:53
  • How do you determine if some initialization is required? Commented Jun 22, 2020 at 7:53
  • will check if required module is already download or not @deHaar Commented Jun 22, 2020 at 7:53
  • @NishantPardamwar does your singleton have methods on it that you're calling? Couldn't you just move the initialization logic into these said methods? Commented Jun 22, 2020 at 8:02

3 Answers 3

2

I wouldn't use object for this type of singleton. You can do it more like the Java way.

class Singleton private constructor() {

    companion object {
        private var _instance = Singleton()
        val instance: Singleton 
            get() = synchronized(this) {
                doSomeInitializationIfRequired()
                _instance
            }
    }

}

If you need parameters for the constructor or for doSomeInitializationIfRequired(), you can replace val instance with a getInstance function. This is common on Android where your singleton might need a reference to the Application instance.

class Singleton private constructor(val application: Application) {

    companion object {
        private val instance: Singleton? = null

        fun getInstance(application: Application): Singleton = synchronized(this) {
            val value = instance ?: Singleton(application).also { instance = it }
            doSomeInitializationIfRequired(application)
            value
        }
    }

}
Sign up to request clarification or add additional context in comments.

2 Comments

Marking this as Accepted answer as there is no alternative with kotlin object but would like to see this addressed in future kotlin version if possible.
I think it's unlikely the language will get first-class support for something that's kind of an unusual requirement. A side-effect each time you get an object reference is inconsistent, because nothing stops you from assigning that reference to some other variable/property where it won't have a side-effect each time you access it.
2

You can create a custom getter function for instance property and add your additional checks there

object Singleton {
    val instance: Singleton
        get() {
            println("doing something extra")
            return this
        }
}

2 Comments

what is Single here ?
But the getter() will be bypassed if you ever skip using .instance before using the Snigelton.
1

You can use a bit of abstraction, create an interface (whatever you want to name it). And define all the possible methods and properties, that singleton should have:

interface ISomeSingleton {
    fun something()
}

Then create a private implementation as a singleton:

private object SingletonImpl : ISomeSingleton {
    override fun something() = println("hello")
}

At last define a top-level field with a custom getter, which returns the implementation:

val SomeSingleton: ISomeSingleton
    get() {
        // do your fancy stuff here
        return SingletonImpl
    }

Now you're able to get the instance of ISomeSingleton via the SomeSingleton field. And your initialization code is run always

1 Comment

that init will be called only once, i want to be able to call my doSomeInitializationIfRequired() everytime when singleton instance is called

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.