简体   繁体   中英

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?

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();
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM