Thomas Nelson
Thomas Nelson

Reputation: 683

null pointer exception when overriding a parameterless method with a field

I am working through "Programming in Scala" and it says that you can override a parameterless method with a field, ad gives the following example:

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

class ArrayElement(conts: Array[String]) extends Element {
    val contents:Array[String] = conts
}

val a = Array("Hello", "mom")
println(a(0))
val x = new ArrayElement(a)
println(x.contents)
println("Hello, " + x.height)

However this code produces a null pointer exception for me. Replacing "val contents:" with "def contents:" works fine. I can't really understand where the null pointer exception is coming from, if the contents array is indeed being correctly passed. It seems to be coming from the "val height = contents.length" line, because replacing those with "def height" also runs correctly. What am I not understanding about this example?

Upvotes: 3

Views: 435

Answers (1)

Kai Sternad
Kai Sternad

Reputation: 22830

This is about evaluation order in your abstract class.

vals are evaluated once at initialization time, whereas defs are evaluated every time they are accessed. The NullPointerException happens during initialization time, because height accesses contents at a time when it hasn't been initialized yet.

As you suggest, turning height and width into defs is one way to prevent the problem.

Upvotes: 2

Related Questions