我有以下代码描述枚举:
package aicore2.worker.scheduling
object Priority extends Enumeration with App {
type Priority = Value
/**
* Action is performed immediately, any running action is interrupted
* and action queue is cleared
*/
val ACHTUNG = Value
/**
* Action is performed before all LOW, NORMAL and HIGHER actions
*/
val HIGH = Value
/**
* Action is performed before all NORMAL and LOW actions
*/
val HIGHER = Value
/**
* Standart priority for most actions
*/
val NORMAL = Value
/**
* Action is added to the end of the queue. Desired for non-critical maintenance actions
*/
val LOW= Value
Priority.values foreach println
}
和测试:
package aicore2.worker.scheduling
import org.junit.Assert._
import org.junit.Test
import aicore2.worker.scheduling.Priority._
class PriorityTypeTests {
@Test
def toStringTest() {
//Priority.values foreach println
//Priority.main(Array("2"))
assertEquals(HIGH.toString(), "HIGH")
}
@Test
def stringParseTest() {
assertEquals(Priority.withName("HIGH"), HIGH)
}
}
当我运行测试时,我得到NPE(HIGH = null)。
当我将优先级作为应用程序运行时,我得到了我想要的任何内容: ACHTUNG 高 更高 正常 LOW
在运行test之前调用Priority.main()时得到的结果相同且没有NPE。 当我从Priority标头(“with App”)中删除App trait mix-in时,所有测试都按预期传递。 我理解当我混合应用程序特征时,初始化顺序有些奇怪,但我是Scala(来自Java领域的难民)的新手,并且还没有足够的经验来解决问题。
答案 0 :(得分:2)
App
表示在运行main
方法之前,成员不会被初始化。在REPL中尝试以下内容:
object A { val x = "foo" }
object B extends App { val x = "foo" }
A.x // = "foo"
B.x // = null
在带有App的Enumeration类中,所有成员都是null
,直到您调用其main
方法。因此,来自测试方法的HIGH.toString()
会导致nullPointerException,因为HIGH
尚未初始化。
因此,提供Enumeration
App
特征似乎是一个非常糟糕的主意。
答案 1 :(得分:1)
App
特征扩展了DelayedInit
特征,这延迟了其成员的初始化,直到明确请求它为止(在App
特征的应用程序开始时)。您应该将其视为主要方法制作对象。
有关App
和DelayedInit
特征的更多信息,请阅读Scala 2.9.0 release notes。