对象交叉引用和初始化顺序

时间:2013-02-09 15:18:33

标签: scala object initialization initialization-order

我有以下代码:

abstract class SuperClass (cs: Seq[C]) {
  def init {}
}

object A extends SuperClass(Seq(B, C))
object B extends SuperClass(Seq(A, D))
object C extends SuperClass(Seq(A, B))
object D extends SuperClass(Seq(C, B, A))
object E extends SuperClass(Seq(B, A, B))

object Initializer {
  def init {
    A.init
    B.init
    C.init
    D.init
    E.init
  }
}

所以在开始时,因为每个对象都有一些内容要初始化,我调用

Initializer.init

然后在程序的某个点上,当我使用对象的cs参数时,我得到NullPointerException,因为Seq中引用的其中一个对象确实是null(打印到控制台显示)。即,对引用它们的其他对象init之后调用init的对象的引用,往往设置为null

这是一个有趣的情况。我在这里有一个任意到任意的任意交叉引用,我不知道如何正确地实现初始化而不将其完全引入外部方法(这无论如何都是封装的分解)。特别是用户可能有能力创建自己的单身,扩展SuperClass类。

使用尽可能少的样板文件,这是最好的方法吗?

1 个答案:

答案 0 :(得分:1)

我提出了以下解决方案。它是Instantiating immutable paired objects的一半副本,但是Seq定义的依赖项是一个额外的维度。

abstract class SuperClass (cs: => Seq[SuperClass]) {
  SuperClass.collected += this
  def init {}
}
object SuperClass {
  private val collected = ListBuffer[SuperClass]()
  def init = collected.foreach(_.init)
}
object Initializer {
  def init {
    A // access the root object
    SuperClass.init // call init on all automatically created dependent objects
  }
}