3

Possible Duplicate:
val and object inside a scala class?

Is there a substantive difference between:

class Foo {
  object timestamp extends java.util.Date
}

and

class Foo {
  val timestamp = new java.util.Date {}
}

What does it really mean to have a class with an object field? What are they used for? Are there situations where you must use an object?

Thanks...

Community
  • 1
  • 1

3 Answers3

6

Using an object may be preferable if you need to add behavior to the field. For example:

class Foo {
   object startDate extends java.util.Date {
      def isBusinessDay: Boolean = // ...
   }
}

class Bar {
   lazy val startDate = new java.util.Date {
      def isBusinessDay: Boolean = // ...
   }
}

The type of foo.startDate is foo.startDate.type, and a call to the foo.startDate.isBusinessDay method will be resolved statically.

The type of bar.startDate, on the other hand, is the structural type java.util.Date{ def isBusinessDay: Boolean }. A call to bar.startDate.isBusinessDay will therefore use reflection and incur unnecessary runtime overhead.

Aaron Novstrup
  • 20,967
  • 7
  • 70
  • 108
5

Two differences, one important, one subtle. First, objects are lazily initiated. For your purposes, this means your second example should be

class Foo {
  lazy val timestamp = new java.util.Date {}
}

for them to behave equivalently. More subtly, each object has it's own unique type. In the case of your example, timestamp will have type Foo.timestamp.type. This normally isn't important in practice, but may cause surprises if you are accessing objects reflectively.

Dave Griffith
  • 20,435
  • 3
  • 55
  • 76
  • Picking nits a bit, isn't it the case that in either instance, timestamp has a unique type, but in the object case, the type is predictable, and in the val case it's some anon type? – Eric Bowman - abstracto - Dec 08 '10 at 21:29
  • Ok, looking at your other answer, it seems the reason we see object fields is from code that predates lazy val. I'd say lazy val is almost always preferred. – Eric Bowman - abstracto - Dec 08 '10 at 21:33
  • @Eric Actually, the type is also predictable in the `val` case, but it's a structural type. More in my answer... – Aaron Novstrup Dec 08 '10 at 21:59
  • Yes, object fields are most common in pre-2.6 Scala code, which was when lazy val was added. There aren't many other usecases where they still make sense. – Dave Griffith Dec 09 '10 at 00:04
2

Those do behave basically the same way. I had assumed that class X { object Y ... } would simply provide a namespace for X.Y. I used Y to store (constant) utility data related to X specifically because I expected one unique X.Y. In fact, one new object was constructed for every new X which I discovered when doing memory profiling.

Ben Jackson
  • 90,079
  • 9
  • 98
  • 150