【问题标题】:Singleton with isInitialized check带有 isInitialized 检查的单例
【发布时间】:2018-11-29 09:09:51
【问题描述】:

我正在 Kotlin 中开发一个单例类,但我想检查 lateinit var "instance" 是否已初始化,而不是检查是否为空,但它不起作用。我认为最好像 lateinit 那样初始化 var 而不要像 null var。

companion object {
    private lateinit var instance: GameDAO

    fun getInstance(): GameDAO {
        if (!::instance.isInitialized) {
            synchronized(this) {
                instance = GameDAO()
            }
        }
        return instance
    }
}

编译器显示下一个错误: enter image description here

【问题讨论】:

标签: android kotlin


【解决方案1】:

我认为您想要达到的目标最好使用lazy 函数在第一次请求时懒惰地初始化一个值。详情请见here

例如

companion object {
    val instance: GameDAO by lazy { GameDAO() }
}

您不需要单独的getInstance 函数:您可以直接访问instance 属性,它会在第一次请求时被初始化(以线程安全的方式)。

这是假设您只希望在第一次请求时初始化对象(即延迟初始化)。如果您希望始终创建它,那么您可以构建它并立即将其分配给变量/属性。

【讨论】:

  • 最好使用by lazy 而不是= lazy (kotlinlang.org/docs/reference/delegated-properties.html#lazy)。
  • 同意,谢谢@AlexeyRomanov。已相应地更新了我的答案。
  • 如果没有可用的默认构造函数怎么办?
  • 您不需要使用默认构造函数。传递给lazy 的 lambda 代码可以访问范围内的任何变量,因此可以使用这些变量来构造需要参数的对象。 (显然这些变量也需要自己初始化。)
【解决方案2】:
object GameDao {
    fun hereGoesYourFunctions()
}

在这里调用GoesYourFunctions 将初始化GameDao 类。

【讨论】:

    【解决方案3】:

    您可以尝试更好的方法:

    class SingletonClass private constructor() {
    
    init {
        println("This ($this) is a singleton")
    }
    
    private object Holder {
        val INSTANCE = SingletonClass()
    }
    
    companion object {
        val instance: SingletonClass by lazy {
            Holder.INSTANCE
        }
    }
    

    【讨论】:

    • 不,这在 Kotlin 中根本不是更好的方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多