scala中一个奇怪的NullPointerException

时间:2016-03-02 08:49:14

标签: scala

代码在这里:

abstract class Element {
  def contents: Array[String]
  val height = contents.length
  val width = if(height ==0 ) 0 else contents(0).length

  override def toString = contents(0)
}
class ArrayElement(override val contents: Array[String]) extends Element

class LineElementT(s: String) extends Element {
  override def contents = Array(s)
}

class LineElementF(s: String) extends Element {
  override val contents = Array(s)
}

LineElementF之外,这三个子类都可以,NullPointerException在使用val lef = new LineElementF("Wrong")创建实例时会抛出padding

2 个答案:

答案 0 :(得分:4)

此NPE发生在高度初始化时。在高度初始化时,LineElementF的val内容未初始化。

你可以通过将高度和宽度都声明为懒惰来避免这种NPE:

lazy val height = contents.length
lazy val width = if(height ==0 ) 0 else contents(0).length

答案 1 :(得分:1)

Scala语言也有一个特殊的语法(有时称为early definitions or early initilizer),它允许在其超类的构造函数之前执行子类的构造函数:

class LineElementEI(s: String) extends {
  override val contents = Array(s)
} with Element

澄清为什么常规的“延迟初始化”不适用于LineElementF:在超类的主体中,您试图评估contents.length,但子类的主体仅被评估 超类之后,contents仍为null。您可以使用所有依赖于子类初始化的字段进行延迟求值来解决它,也可以更改初始化顺序,如上所示。