![](/img/trans.png)
[英]Initializing map in companion object throws ExceptionInInitializerError
[英]Initializing companion object after inner objects
假設我想創建密封類,填充一些對象。 然后我想創建所有這些對象的列表,所以我在companion對象中創建列表:
fun main() {
println(Color.Blue)
println(Color.allColors)
}
sealed class Color {
object Red : Color();
object Blue : Color();
companion object {
val allColors = listOf(
Red,
Blue
)
}
}
但是,上面代碼的問題是,當第一次直接調用Color.Blue
時,伴隨對象在Blue
之前被初始化,因此結果列表包含[Red, null]
。 這是雙重問題,因為Kotlin假定列表包含非空值。
我知道上面的例子很簡單,我可以用enum
替換sealed class
,但這只是一個簡化的例子。 在許多情況下,在枚舉上使用密封類是有益的(例如,當您需要將類型參數添加到單個對象時)。
用最少量的樣板和分配對象來解決這個問題的最佳方法是什么? 我提出了兩個解決方法,但我不喜歡其中任何一個:
fun main() {
println(Color.Blue)
println(Color.allColors)
}
sealed class Color {
object Red : Color();
object Blue : Color();
companion object {
val allColors by lazy {
listOf(
Red,
Blue
)
}
}
}
上面的解決方案看起來很好,並沒有引起太多鍋爐板,但它創建了一個額外的對象,它永遠存在於伴隨對象中的每個屬性。 我還需要在任何其他屬性上重復lazy關鍵字。
fun main() {
println(Color.Blue)
println(Color.allColors)
}
sealed class Color {
object Red : Color();
object Blue : Color();
private object Initializer {
val allColors = listOf(
Red,
Blue
)
}
companion object {
val allColors: List<Color>
get() = Initializer.allColors
}
}
此方法的好處是只為伴隨對象中的所有屬性創建一個對象,但它會創建許多額外的樣板。
有沒有更好的方法來實現這一目標?
編輯:此案例的Kotlin問題跟蹤器存在問題: https : //youtrack.jetbrains.com/issue/KT-8970
sealed class Color(var meh:Int) {
object Red : Color(10)
object Blue : Color(20)
companion object {
private var colorsList:List<Color>? = null
val allColors:List<Color>
get() = colorsList?:run{
colorsList = listOf(
Red,
Blue
)
colorsList!!
}
}
}
這是永遠的單身人士。 這只是另一種方式。 但Initializer對象看起來更干凈。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.