7

Which solution should be generally preferred, considering that the change is source compatible?

This

object Foo {
  val Bar = new Baz(42, "The answer", true)
}

or this?

object Foo {
  object Bar extends Baz(42, "The answer", true)
}
soc
  • 27,983
  • 20
  • 111
  • 215
  • I would say first one is better if you want to modularize your API differently in the future without too much modification... but since the change is source compatible you can keep the second until needed. – Alois Cochard May 25 '11 at 13:37
  • Possible duplicate of [val and object inside a scala class?](http://stackoverflow.com/questions/3448691/val-and-object-inside-a-scala-class) – Bergi May 25 '16 at 03:59

2 Answers2

8

The functional difference between the two constructs is that object Bar is only created when it is needed, while val Bar is created as soon as object Foo is used. As a practical matter, this means you should use the object (or lazy val) if the right-hand side is expensive and won't always be needed. Otherwise, val is probably simpler.

Also, note that if the class Baz is final, you won't be able to use the object style since you can't extend Baz (though you can still use lazy val if you want to defer creation until it's needed).

Rex Kerr
  • 166,841
  • 26
  • 322
  • 407
  • Sorry, I wasn't clear enough. I meant with `final` that the variable `Bar` won't be reassigned. Isn't the bytecode for `object` slightly simpler than the code for `lazy val`? – soc May 25 '11 at 14:06
  • @soc - Yes, `lazy val` is more complex code (and threadsafe). And I edited my answer to make it clearer what I meant regarding `final`. – Rex Kerr May 25 '11 at 14:13
  • @soc - Doesn't look like it to me; the object initializer code doesn't seem to be thread-aware. You can check the bytecode. – Rex Kerr May 25 '11 at 14:40
  • Afaik it uses the same strategy like singleton enums in Java where the VM guarantees thread-safety, not the bytecode. – soc May 25 '11 at 15:03
  • @soc - Could be. This isn't something I'm terribly familiar with. – Rex Kerr May 25 '11 at 16:33
2

I say the first since in the second, you are creating a new class but don't add any information (no overriding of methods, values or new ones).

IttayD
  • 28,271
  • 28
  • 124
  • 178