【问题标题】:Singleton class in Kotlin with initKotlin 中带 init 的单例类
【发布时间】:2021-07-20 09:51:28
【问题描述】:

我只是希望澄清一些在 Kotlin 中使用单例的方法。

我有这门课:

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")
 }
}

还有这个测试功能:

1. TestClass.instance.runSync1()
2. TestClass.runSync2()
3. TestClass().runSync1()
  1. 当调用函数 1 两次时,伴随对象内的 init 将被调用一次。所以只创建了一个 TestClass 实例并运行 runSync1() 两次,对吗?
  2. 当调用函数 2 两次时,伴随对象内的 init 将被调用一次。所以只创建了一个 TestClass 实例并运行 runSync2() 两次,对吗?那么1和2有什么区别呢?
  3. 两次调用函数 2 时,2 个 TestClass 实例 crated,2 个类内的 init 将运行,2 个 runSync1 将独立运行?

您能否提供更多说明并更正错误的部分?

【问题讨论】:

  • 您的代码中没有function1function2,请使用准确的名称,以便我们更好地理解问题
  • 没有实际问题,只是澄清一下。正如您在标记为 1、2、3 的“以及此测试功能”部分中看到的。当提到“功能1”时,它指的是标记为1的功能->“TestClass.instance.runSync1()”蚂蚁等。

标签: android kotlin singleton


【解决方案1】:

在理解伴随对象时要记住的一件事是

在加载(解析)与 Java 静态初始化器的语义匹配的相应类时初始化伴随对象。

所以companion对象内的init块只会被执行一次,当TestClass被加载时,与名为instance的属性相同,它将被分配一个TestClass的对象仅在 class 加载时间一次。

为了更好地理解这一点,您可以查看转换为 java 的代码,它看起来像

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

【讨论】:

    猜你喜欢
    • 2019-01-20
    • 2017-03-16
    • 2018-05-06
    • 2020-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多