我在REPL中创建了这个对象。然后在下面的附图中测试其设置顺序。结果令人困惑。
object T {
val default = A
var options = List[P]()
println(options)
sealed trait P
object A extends P {
override def toString = "A"
println(T.options)
println("A")
}
object B extends P {
override def toString = "B"
println(T.options)
println("A")
}
object C extends P {
override def toString = "C"
println(T.options)
println("A")
}
}
答案 0 :(得分:4)
在第一次运行
T
中,似乎只构造了内部对象A
。 为什么对象B
和对象C
不打印任何东西?
因为他们没有初始化,所以他们只是宣布。打印出A
的原因是:
val default = A
导致A
初始化。因此,初始化的顺序是:
T
s default
变量导致A
初始化A
初始化并打印null
T
现在继续初始化,现在将值设置为options
现在,任何进一步的调用都将打印列表的内容,而不是null
。
另请注意,第一次运行中的
println(T.options)
返回" null"。是 这是因为首先设置内部对象然后设置外部对象 其他成员是否已成立?
这是因为println(T.options)
发生在A
的构造函数中,它位于options
构造函数内的T
初始化之前。
在输入
T.A
时,没有打印任何内容,因为该对象已经设置好。
这很有道理,A
没有任何其他需要初始化的内容。
在输入
T.B
时,它会设置B
对象并打印T.options
正确地是List()
而不是null
。
没错,因为一旦你调用T.B
,你就已经通过T
的构造函数初始化了列表。