强制初始化Scala单例对象

强制初始化Scala单例对象,scala,object,Scala,Object,我正在开发一个基于Dozer的自动绘图框架。我不会详细讨论,因为它与问题无关,但一般来说,它应该允许从类A到类B的简单转换。我想注册一个类的伴生对象的投影 下面是一个(简化的)示例,说明我希望它如何工作,以及一个规范测试,确保投影正确注册 不幸的是,这不起作用。据我所知,这是因为没有任何东西可以初始化伴生对象。事实上,如果我调用对象上的任何方法(如注释掉的hashCode调用),则投影被正确注册 我的问题是-如何在JVM启动时自动初始化对象?如果需要,我不介意扩展特性或其他东西 谢谢 class

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

下面是一个(简化的)示例,说明我希望它如何工作,以及一个规范测试,确保投影正确注册

不幸的是,这不起作用。据我所知,这是因为没有任何东西可以初始化伴生对象。事实上,如果我调用对象上的任何方法(如注释掉的hashCode调用),则投影被正确注册

我的问题是-如何在JVM启动时自动初始化对象?如果需要,我不介意扩展特性或其他东西

谢谢

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
  }
}

简短回答:你不能。Scala对象是惰性的,在第一次引用之前不会初始化。你可以引用该对象,但之后你需要一种方法来确保执行的代码得到执行,从而将问题还原为原始问题。

你可以通过usi强制实例化
a
,以包含伴随对象在对象中定义apply()方法或某种其他类型的工厂方法,而不是直接使用
newa()
构造函数


这不会导致在JVM启动时初始化对象,我认为正如另一个答案中所指出的那样,这通常是无法完成的。

正如Dave Griffith和Don Roby已经指出的那样,通常不能在JVM启动时完成。但是,也许可以等到第一次使用您的框架后再进行初始化? 如果是这样,并且您不介意使用脆弱的反射技巧,那么在-->方法中,您可以获得对伴生对象的引用,并使其自身初始化


您可以从中开始。

最终执行以下操作:

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]

}
trait ProjektionAware和delayedint
{
private val initCode=new ListBuffer[()=>Unit]
覆盖def delayedInit(主体:=>装置)
{
initCode+=(()=>正文)
}
def registerProjektions()
{

对于(proc,我们可以使用这种方法来确保首先初始化伴随对象,然后实例化类

object B {
    val i = 0
    def apply(): B = new B()
}
class B {
    // some method that uses i from Object B
    def show = println(B.i)
}

// b first references Object B which calls apply()
// then class B is instantiated
val b = B()

这当然是正确的,但并没有回答他的实际问题。不过,这可能还不够,也可能不足以得到他的用例。但如果有一些特性(a la
App
)可以扩展以强制初始化具有该特性的对象,那岂不是很好。例如
object EarlyBird extensed ForceInit{…
。这有多难实现?