I have an abstract class with an unimplemented method numbers
that returns a list of numbers, and this method is used in another val property initialization:
abstract class Foo {
val calcNumbers = numbers.map(calc)
def numbers: List[Double]
}
The implementing class implements using a val expression:
class MainFoo extends Foo {
val numbers = List(1,2,3)
}
This compiles fine, but at run time it throws a NullPointerException and it points to the line of val calcNumbers
:
[error] (run-main-0) java.lang.ExceptionInInitializerError
[error] java.lang.ExceptionInInitializerError
...
[error] Caused by: java.lang.NullPointerException
...
However when I changed the implemented method to def, it works:
def numbers = List(1,2,3)
Why is that? Does it have something to do with initialization order? How can this be avoided in the future as there is no compile time error/warning? How does Scala allow this unsafe operation?
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…