我一直认为scala对象只是单例java对象的简写 - 也就是说,我希望它们的行为类似于保证单例实例化的对象。然后我遇到这样的事情,我不明白:
object Test extends App{
var x ="a"
override def main(args:Array[String]):Unit = {
println(x )
}
}
打印 null 而不是“a”。
查看生成的类,我得到一个Test $ .class,它是对象定义;但是,实例值“a”是使用生成的delayedInit在伴随的Test类中定义的。有人可以说明这是如何实例化的吗?很明显,我对此的心理模型是不正确的。
答案 0 :(得分:4)
让我们先来看看App
以及它是如何运作的。 documentation of App显示以下警告:
应该注意的是,这个特性是使用 DelayedInit功能,这意味着对象的字段将 在主方法执行之前尚未初始化。
还应该注意,主要方法通常不需要 被覆盖:目的是将整个班级的身体变成 “主要方法”。如果你知道什么,你应该只选择覆盖它 你在干嘛。
好的,太好了。现在我们知道了这两个事实,让我们修复你的代码。我们可以考虑两种可能的解决方案:
当我们知道自己在做什么时,我们只会覆盖主要方法:
object Test extends App{
var x ="a"
println(x )
}
或者我们可以选择定义main
方法,但不能扩展App
:
object Test {
var x ="a"
def main(args:Array[String]):Unit = {
println(x )
}
}
您对对象的理解是正确的。令人困惑的是App
实施的DelayedInit。快乐的编码;)