Why does a null pointer exception occur in the code below?
object Test extends App{
trait MyTrait[A]{ self =>
val seq: Seq[A]
val size = seq.size // null pointer here
}
val p = new MyTrait[Int]{
val seq = Seq(1,2,3)
}
}
If I change the size field to lazy then it's ok.
Fields are initialized in the order they are mixed in--so first everything in the trait happens, and then the val
is assigned to Seq(1,2,3)
(since you're essentially mixing in an anonymous trait).
As you have discovered, lazy val
is often a way out of this mess: you don't actually call seq.size
until you need it, which is after you have populated the seq
field.
The style recommendation is to avoid vals in traits, in favor of defs and lazy vals, because of init order land mines.
Sample conversation: https://groups.google.com/forum/?fromgroups=#!topic/scala-user/nrOrjPOYmb0
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With