Kotlin `object` 初始化顺序导致意外的 null 实例

mae*_*tro 2 null jvm heap-memory intellij-idea kotlin

考虑以下代码:

sealed class DataType<T : Any> {
    abstract fun inputToType(input: String): T
    abstract fun typeToSql(value: T): String

    companion object {
        val all = listOf(StringDt, LongDt)
    }
}

object StringDt : DataType<String>() {
    override fun inputToType(input: String) = input
    override fun typeToSql(value: String) = "\"${value}\""
}

object LongDt : DataType<Long>() {
    override fun inputToType(input: String) = input.toLong()
    override fun typeToSql(value: Long) = value.toString()
}

val dataTypeList = listOfNotNull(StringDt, LongDt)

println(dataTypeList)
println(DataType.all)
Run Code Online (Sandbox Code Playgroud)

需要考虑的事项:

  • object根据文档(以及我的理解)是单例并且总是实例化
  • 这两个对象 (StringDtLongDt) 非常相似

结果println(DataType.all)表明其中一个对象未​​初始化。这怎么可能?我希望所有列表元素都被初始化。

IntelliJ 版本:CE 2020.2 Kotlin 插件版本:1.4.0-release-IJ2020.2-1

下面是一个运行示例,显示静态列表有一个 null 元素,而非静态列表包含两个已初始化的对象。

And*_*ana 5

这是由于循环静态初始化而发生的。很难用两个词来解释这个问题,但您可以在这里阅读。

all要修复此行为,您可以像这样更改初始化:

val all by lazy { listOf(StringDt, LongDt) }
Run Code Online (Sandbox Code Playgroud)