What is the difference between declaring a field as val
, lazy val
and object
inside a scala class, as in the following snippet:
I'm not sure that aioobe recognized the significance of his answer, but the different types actually represent a critical difference between vals
and objects
. In particular, the val
and lazy val
have a structural type (e.g. A{def foo: Int}
), while the object
has a singleton type. As a result, calls to the foo
method on the val
s involve reflection, while calls to the foo
method on the object
do not:
class A
class B {
val a1 = new A { def foo = printStack }
object a2 extends A { def foo = printStack }
lazy val a3 = new A { def foo = printStack }
def printStack() =
new Exception().getStackTrace take 3 foreach println
}
scala> val b = new B
b: B = B@5c750
scala> b.a1.foo // the val
line124$object$$iw$$iw$B.printStack(<console>:12)
line124$object$$iw$$iw$B$$anon$1.foo(<console>:7)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
scala> b.a2.foo // the object
line124$object$$iw$$iw$B.printStack(<console>:12)
line124$object$$iw$$iw$B$a2$.foo(<console>:8)
line128$object$$iw$$iw$.<init>(<console>:9)
scala> b.a3.foo // the lazy val
line124$object$$iw$$iw$B.printStack(<console>:12)
line124$object$$iw$$iw$B$$anon$2.foo(<console>:9)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)