为什么第三次访问此数组会返回null?

Tom*_*ral 1 arrays null scala nullpointerexception

我在Scala中写俄罗斯方块作为练习,我遇到了这种奇怪的行为:

abstract class Orientation(protected val index: Int) {
  private[Orientation] val impls: Array[Orientation] = Array(OrientedLeft, OrientedUp, OrientedRight, OrientedDown)

  def rotateCounterClockwise = impls(
      if (index == 0) 3
      else index - 1
  )

  def rotateClockwise = impls((index + 1) % 4)
}

object OrientedLeft extends Orientation(0) {
  override def toString = "Left"
}
object OrientedUp extends Orientation(1) {
  override def toString = "Up"
}
object OrientedRight extends Orientation(2) {
  override def toString = "Right"
}
object OrientedDown extends Orientation(3) {
  override def toString = "Down"
}

object Test extends Application {
  var orientation: Orientation = OrientedUp

  for (i <- 0 until 20) {
    println("Oriented to: "+ orientation)
    orientation = orientation.rotateClockwise
  }
}
Run Code Online (Sandbox Code Playgroud)

Running Test提供此输出:

Oriented to: Up
Oriented to: Right
Oriented to: Down
Oriented to: null
Run Code Online (Sandbox Code Playgroud)

其次是java.lang.NullPointerException.我的意思是:这到底是怎么回事?

Rég*_*les 6

只需移动impls一个伴侣对象:

object Orientation {
  private val impls: Array[Orientation] = Array(OrientedLeft, OrientedUp, OrientedRight, OrientedDown)
}
abstract class Orientation(protected val index: Int) {
  import Orientation._
  def rotateCounterClockwise = impls(
      if (index == 0) 3
      else index - 1
  )

  def rotateClockwise = impls((index + 1) % 4)
}
Run Code Online (Sandbox Code Playgroud)

您遇到此错误的原因是您具有循环初始化依赖关系:每次实例化时Orientation,您都会访问这四个Orientation单例.简单地说,访问OrientedUp强制其实例化,这反过来又迫使所有四个单身人士(包括他OrientedUp自己)的实例仍然被构建.这就是为什么你为这个"仍然被构造"的值得到null.