monk
monk

Reputation: 228

A weird NullPointerException in scala

the code goes here:

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)
}

these three sub-classes are OK except the LineElementF, which throws an NullPointerException when creating instance with val lef = new LineElementF("Wrong")

Upvotes: 4

Views: 342

Answers (2)

bluenote10
bluenote10

Reputation: 26530

The Scala language also has a special syntax (sometimes called early definitions or early initilizer), which allows to execute the constructor of a subclass before the constructor of its superclass:

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

To clarify why regular "late initialization" does not work with your LineElementF: In the body of the superclass you are trying to evaluate contents.length, but the body of the subclass is only evaluated after the superclass, so contents is still null. You can either solve it be using lazy evaluation on all fields which depend on subclass initialization or change the initialization order as shown above.

Upvotes: 1

Nyavro
Nyavro

Reputation: 8866

This NPE happens at height initialization. At the moment of height initialization val contents of LineElementF is not initialized.

You can avoid this NPE by declaring both height and width as lazy:

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

Upvotes: 4

Related Questions