Reputation: 683
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
Reputation: 22830
This is about evaluation order in your abstract class.
val
s are evaluated once at initialization time, whereas def
s 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 def
s is one way to prevent the problem.
Upvotes: 2