[英]Kotlin `object` initialization order leads to unexpected null instance
Consider the following code:考虑以下代码:
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)
Things to consider:需要考虑的事项:
object
as per documentation (and my understanding as well) is singleton and always instantiated object
根据文档(以及我的理解)是 singleton 并且总是实例化StringDt
and LongDt
) are quite similar这两个对象( StringDt
和LongDt
)非常相似The result of println(DataType.all)
shows that one of the objects are not initialized. println(DataType.all)
的结果显示其中一个对象未初始化。 How is that possible?这怎么可能? I would expect all the list elements to be initialized.我希望所有列表元素都被初始化。
IntelliJ version: CE 2020.2 Kotlin plugin version: 1.4.0-release-IJ2020.2-1 IntelliJ 版本:CE 2020.2 Kotlin 插件版本:1.4.0-release-IJ2020.2-1
Here's a running example which shows that the static list has a null element, while the non-static one contains both objects initialized.这是一个运行示例,显示 static 列表有一个 null 元素,而非静态列表包含两个已初始化的对象。
It happens due to cyclical static initializations.这是由于循环 static 初始化而发生的。 It's pretty hard to explain this problem in two words but you can read about it here .很难用两个词来解释这个问题,但您可以在此处阅读相关内容。
To fix this behavior you can change all
initialization like this:要修复此行为,您可以像这样更改all
初始化:
val all by lazy { listOf(StringDt, LongDt) }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.