Kotlin `object` 初始化顺序导致意外的空实例
Kotlin `object` initialization order leads to unexpected null instance
考虑以下代码:
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)
需要考虑的事项:
object
根据 documentation(以及我的理解)是单例并且总是实例化
- 两个对象(
StringDt
和LongDt
)非常相似
println(DataType.all)
的结果显示其中一个对象没有初始化。这怎么可能?我希望所有列表元素都被初始化。
IntelliJ 版本:CE 2020.2
Kotlin 插件版本:1.4.0-release-IJ2020.2-1
这是一个 running example,它显示静态列表有一个空元素,而非静态列表包含两个已初始化的对象。
它是由于循环静态初始化而发生的。很难用两个词来解释这个问题,但你可以阅读它 here。
要解决此问题,您可以像这样更改 all
初始化:
val all by lazy { listOf(StringDt, LongDt) }
考虑以下代码:
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)
需要考虑的事项:
object
根据 documentation(以及我的理解)是单例并且总是实例化- 两个对象(
StringDt
和LongDt
)非常相似
println(DataType.all)
的结果显示其中一个对象没有初始化。这怎么可能?我希望所有列表元素都被初始化。
IntelliJ 版本:CE 2020.2 Kotlin 插件版本:1.4.0-release-IJ2020.2-1
这是一个 running example,它显示静态列表有一个空元素,而非静态列表包含两个已初始化的对象。
它是由于循环静态初始化而发生的。很难用两个词来解释这个问题,但你可以阅读它 here。
要解决此问题,您可以像这样更改 all
初始化:
val all by lazy { listOf(StringDt, LongDt) }