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