构造嵌套对象和成员变量的顺序

时间:2016-08-24 13:07:40

标签: scala

我在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")
  }
}
  1. 在第一次运行中,T,似乎只构造了内部对象A.为什么对象B和对象C不打印任何东西?

  2. 另请注意,第一次运行中的println(T.options)返回“null”。这是因为设置了第一个内部对象,然后设置了其他成员的外部对象吗?

  3. 在输入T.A时,没有打印任何内容,因为该对象已经设置好。

  4. 在键入T.B时,它会设置B对象并正确打印T.options,即List()而不是null。

  5. enter image description here

1 个答案:

答案 0 :(得分:4)

  

在第一次运行T中,似乎只构造了内部对象A。   为什么对象B和对象C不打印任何东西?

因为他们没有初始化,所以他们只是宣布。打印出A的原因是:

val default = A

导致A初始化。因此,初始化的顺序是:

  1. T s default变量导致A初始化
  2. A初始化并打印null
  3. T现在继续初始化,现在将值设置为options
  4. 现在,任何进一步的调用都将打印列表的内容,而不是null

      

    另请注意,第一次运行中的println(T.options)返回" null"。是   这是因为首先设置内部对象然后设置外部对象   其他成员是否已成立?

    这是因为println(T.options)发生在A的构造函数中,它位于options构造函数内的T初始化之前。

      

    在输入T.A时,没有打印任何内容,因为该对象已经设置好。

    这很有道理,A没有任何其他需要初始化的内容。

      

    在输入T.B时,它会设置B对象并打印T.options   正确地是List()而不是null

    没错,因为一旦你调用T.B,你就已经通过T的构造函数初始化了列表。