Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Singleton class in Kotlin with init

I just to wish clarify some methodology using singletons in Kotlin.

I have this class:

class TestClass {

companion object {
    val instance = TestClass()

    fun runSync2() {
        Log.d("TAG", "Running sync2")
    }
    
    init {
        Log.d("TAG", "Init companion")
    }
}

init {
    Log.d("TAG", "Init class")
}

fun runSync1() {
    Log.d("TAG", "Running sync1")
 }
}

And this test functions:

1. TestClass.instance.runSync1()
2. TestClass.runSync2()
3. TestClass().runSync1()
  1. When calling function 1 twice, init inside companion object will be called once. So only one instance of TestClass is created and run runSync1() twice, correct?
  2. When calling function 2 twice, init inside companion object will be called once. So only one instance of TestClass is created and run runSync2() twice, correct? So what is the difference between 1 and 2?
  3. When calling function 2 twice, 2 instances of TestClass crated, 2 init inside class will run and 2 runSync1 will run independently?

Can you please provide more clarification and correct the wrong parts?

like image 709
Dim Avatar asked Feb 05 '26 16:02

Dim


1 Answers

When understanding the companion objects one thing to remember is that

A companion object is initialized when the corresponding class is loaded (resolved) that matches the semantics of a Java static initializer.

So the init block inside the companion object will be executed only once, when the TestClass is being loaded, same goes with the property named instance, it will be assigned an object of TestClass only once at class load time.

To better understand this you can look at your code converted to java, which will look something like

public final class TestClass {

    // Property of companion object and the init block are now part of TestClass
    private static final TestClass instance = new TestClass();

    static {
       Log.d("TAG", "Init companion");
    }

    public static final TestClass.Companion Companion = new TestClass.Companion((DefaultConstructorMarker)null);

    public final void runSync1() {
        Log.d("TAG", "Running sync1");
    }

    public TestClass() {
        Log.d("TAG", "Init class");
    }


    public static final class Companion {
        public final TestClass getInstance() {
            return TestClass.instance;
        }

        public final void runSync2() {
            Log.d("TAG", "Running sync2");
        }

        private Companion() { }

        public Companion(DefaultConstructorMarker $constructor_marker) {
            this();
        }
    }
}
like image 104
mightyWOZ Avatar answered Feb 09 '26 05:02

mightyWOZ



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!