Kotlin 中的单例类

新手上路,请多包涵

我想知道如何在 Kotlin 中创建一个单例类,以便我的 Util 类在每次应用程序执行时只实例化一次。但是,当我将 Java 类转换为 kotlin 时,生成了以下代码。

这个对吗?

 companion object {
    private var utilProject: UtilProject? = null

    val instance: UtilProject
        get() {
            if (utilProject == null) utilProject = UtilProject()
            return utilProject!!
        }
}

我可以找到一个相关的 问题,但它是带参数的,没有参数我不会让它转换。

原文由 Khemraj Sharma 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 549
2 个回答

只是

companion object {
    val instance = UtilProject()
}

将完成这项工作,因为 伴随对象 本身是语言级别的单例。

(第 一次 调用伴随对象时将创建 instance 。)

- 更新 -

如果需要控制单例对象的初始化时间,可以为每个类创建一个对象。

 class UtilProject {
    ....
    companion object {
        val instance = UtilProject()
    }
}

class AnotherClass {
    ...
    companion object {
        val instance = AnotherClass()
        const val abc = "ABC"
    }
}

fun main(args: Array<String>) {
    val a = UtilProject.instance // UtilProject.instance will be initialized here.
    val b = AnotherClass.abc // AnotherClass.instance will be initialized here because AnotherClass's companion object is instantiated.
    val c = AnotherClass.instance
}

这里, AnotherClass.instanceAnotherClass.instance 被实际调用之前被初始化。它在 AnotherClass 的伴随对象时被初始化。为了防止它在需要时被初始化,你可以这样使用:

 class UtilProject {
    ....
    companion object {
        fun f() = ...
    }
}

class AnotherClass {
    ...
    companion object {
        const val abc = "ABC"
    }
}

object UtilProjectSingleton {
    val instance = UtilProject()
}

object AnotherClassSingleton {
    val instance = AnotherClass()
}

fun main(args: Array<String>) {
    UtilProject.f()
    println(AnotherClass.abc)

    val a = UtilProjectSingleton.instance // UtilProjectSingleton.instance will be initialized here.
    val b = AnotherClassSingleton.instance // AnotherClassSingleton.instance will be initialized here.

    val c = UtilProjectSingleton.instance // c is a.
}

如果你不关心每个单例何时初始化,你也可以像这样使用它:

 class UtilProject {
    ....
    companion object {
        fun f() = ...
    }
}

class AnotherClass {
    ...
    companion object {
        const val abc = "ABC"
    }
}

object Singletons {
    val utilProject = UtilProject()
    val anotherClass = AnotherClass()
}

fun main(args: Array<String>) {
    val a = Singletons.utilProject
    val b = Singletons.anotherClass
}

总之,

objectcompanion object 是 Kotlin 中的一个单例对象。

您可以在一个或多个 对象 分配变量,然后像使用单例一样使用这些变量。

objectcompanion object 在第一次使用时被实例化。 val s and var s in an object are initialized when the object is first instantiated (ie, when the object 首次使用)。

编辑:William Hu 在评论中说“a companion object 是加载类的时间。”

原文由 Naetmul 发布,翻译遵循 CC BY-SA 4.0 许可协议

带参数的变体

open class SingletonHolder<out T: Any, in A>(creator: (A) -> T) {
    private var creator: ((A) -> T)? = creator
    @Volatile private var instance: T? = null

    fun getInstance(arg: A): T {
        val checkInstance = instance
        if (checkInstance != null) {
            return checkInstance
        }

        return synchronized(this) {
            val checkInstanceAgain = instance
            if (checkInstanceAgain != null) {
                checkInstanceAgain
            } else {
                val created = creator!!(arg)
                instance = created
                creator = null
                created
            }
        }
    }
}

原文由 Fury Safik 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题