强制初始化Scala单例对象

Ele*_*onk 12 scala object

我正在开发一个基于Dozer的自动映射框架.我不会详细说明,因为它与问题无关,但一般来说它应该允许从A类到B类的简单转换.我想从类的伴随对象中注册投影.

下面是我希望如何工作的(简化)示例,以及确保投影正确注册的Specs测试.

不幸的是,这不起作用.从我可以收集到的,这是因为没有任何东西初始化A伴侣对象.事实上,如果我在A对象上调用任何方法(如注释掉的hashCode调用,则正在正确注册投影.

我的问题是 - 一旦JVM启动,我怎样才能自动初始化A对象?如果有必要,我不介意扩展特性或其他东西.

谢谢.

class A {
  var data: String = _
}

class B {
  var data: String = _
}

object A {
  projekt[A].to[B]

}

"dozer projektor" should {
  "transform a simple bean" in {
//    A.hashCode
      val a = new A
      a.data = "text"
      val b = a.-->[B]

      b.data must_== a.data
  }
}
Run Code Online (Sandbox Code Playgroud)

Dav*_*ith 12

简答:你做不到.Scala对象是惰性的,并且在第一次引用之前不会初始化.您可以引用该对象,但是您需要一种确保执行代码执行的方法,将问题还原到原始问题.

  • 但是,有一些特性(例如"应用程序")可以扩展以强制初始化具有该特征的对象,这不是很好吗.例如`对象EarlyBird扩展了ForceInit {...`.实施起来有多难? (3认同)

Ele*_*onk 4

最终这样做了:

trait ProjektionAware with DelayedInit
{
  private val initCode = new ListBuffer[() => Unit]

  override def delayedInit(body: => Unit)
  {
    initCode += (() => body)
  }


  def registerProjektions()
  {
    for (proc <- initCode) proc()
  }
}

object A extends ProjektionAware {
  projekt[A].to[B]

}
Run Code Online (Sandbox Code Playgroud)

现在,我可以使用类路径扫描库在应用程序引导程序上初始化 ProjektionAware 的所有实例。不理想,但对我有用。