Scala:实例变量和对象初始化

3

我一直认为Scala对象仅仅是Java单例对象的简写 - 也就是说,我期望它们像具有保证单例实例化的对象一样运行。但是我遇到了这样的情况,我不理解:

object Test  extends App{
 var x ="a"

 override def main(args:Array[String]):Unit = {
   println(x )
 }
}

该代码打印null而不是"a"。

查看生成的类,可以得到一个Test$.class,它是对象定义;然而实例值"a"是在一个伴生类Test中通过生成的delayedInit定义的。有人能够说明一下如何实例化吗?显然我对此的心理模型是不正确的。

1个回答

4
让我们先来看看App及其工作原理。 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。祝编码愉快 ;)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接