初始化期间的Scala NullPointerException

初始化期间的Scala NullPointerException,scala,gatling,Scala,Gatling,考虑下面的例子,这是我所拥有的一个简化版本。numberOfScenarios是这里最重要的变量:我通常使用硬编码的数字,而不是它,但我试图看看是否有可能计算值: object ScenarioHelpers { val identifierList = (1 to Scenarios.numberOfScenarios).toArray val concurrentIdentifierQueue = new ConcurrentLinkedQueue[Int](identifi

考虑下面的例子,这是我所拥有的一个简化版本。numberOfScenarios是这里最重要的变量:我通常使用硬编码的数字,而不是它,但我试图看看是否有可能计算值:

object ScenarioHelpers {
    val identifierList = (1 to Scenarios.numberOfScenarios).toArray
    val concurrentIdentifierQueue = new ConcurrentLinkedQueue[Int](identifierList.toSeq)
}

abstract class AbstractScenario {
    val identifier = ScenarioHelpers.concurrentIdentifierQueue.poll()
}

object Test1 extends AbstractScenario {
    val scenario1 = scenario("test scenario 1").exec(/..steps../)
}

object Test2 extends AbstractScenario {
    val scenario2 = scenario("test scenario 2").exec(/..steps../)
}

object Scenarios {
    val scenarios = List(Test1.scenario1, Test2.scenario2)
    val numberOfScenarios = scenarios.length
}

object TestPreparation {
    val feeder = ScenarioHelpers.identifierList.map(n => Map("counter" -> n))
    val prepScenario = scenario("test preparation")
        .feed(feeder)
        .exec(/..steps../)
}
不确定这是否重要,但模拟从执行TestPreparation.prepScenario开始

我看到这段代码包含一个循环依赖项,这使得这种情况本身是不可能的。但我在AbstractScenario中得到一个NullPointerException,其中标识符正在初始化

我不完全理解这一切,但我认为这与最初只是声明VAL有关,而初始化直到后来才发生。因此,当初始化标识符时,concurrentIdentifierQueue尚未初始化,因此为空


我只是想了解NullPointerException背后的原因,以及是否有任何方法可以让它在进行最小更改的情况下工作?谢谢。

特质初始化期间的NPE是一个非常常见的问题。 解决这一问题最可靠的方法是避免实现继承


如果由于某些原因不可能,您可以将有问题的字段标记为lazy val或def而不是val。

您自己回答:

我看到这段代码包含一个循环依赖项,这使得这种情况本身是不可能的。但我在AbstractScenario中得到一个NullPointerException,其中标识符正在初始化

val feeder=场景助手。标识列表。。。调用ScenarioHelpers初始化 val identifierList=1到Scenarios.numberOfScenarios.toArray调用方案初始化 val scenarios=ListTest1.scenario1,Test2.scenario2调用Test1 Inialization,包括AbstractScenario 此处val identifier=ScenarioHelpers.concurrentIdentifierQueue.poll ScenarioHelpers仍在初始化,identifierList为空。
你必须以非循环的方式得到numberOfScenarios。就我个人而言,我会删除identifierList并以另一种方式分配标识符—递增计数器之类

是的,我想这通常是可行的,但是feder现在想要所有东西,不关心def和lazy vals。好的,谢谢你,我不需要删除identifierList,但是你给了我计数器的想法,我用原子整数替换了并发队列。