Difference between case object and object

scala> object foo

defined object foo

scala> case object foocase

defined object foocase

Serialization difference:

scala> foo.asInstanceOf[Serializable]

java.lang.ClassCastException: foo$ cannot be cast to scala.Serializable
... 43 elided

scala> foocase.asInstanceOf[Serializable]

res1: Serializable = foocase

toString difference:

scala> foo

res2: foo.type = foo$@7bf0bac8

scala> foocase

res3: foocase.type = foocase


Here's one difference - case objects extend the Serializable trait, so they can be serialized. Regular objects cannot by default:

scala> object A
defined module A

scala> case object B
defined module B

scala> import java.io._
import java.io._    

scala> val bos = new ByteArrayOutputStream                                            
bos: java.io.ByteArrayOutputStream =  

scala> val oos = new ObjectOutputStream(bos)                                          
oos: java.io.ObjectOutputStream = java.io.ObjectOutputStream@e7da60                   

scala> oos.writeObject(B)

scala> oos.writeObject(A)
java.io.NotSerializableException: A$

Case classes differ from regular classes in that they get:

  1. pattern matching support
  2. default implementations of equals and hashCode
  3. default implementations of serialization
  4. a prettier default implementation of toString, and
  5. the small amount of functionality that they get from automatically inheriting from scala.Product.

Pattern matching, equals and hashCode don't matter much for singletons (unless you do something really degenerate), so you're pretty much just getting serialization, a nice toString, and some methods you probably won't ever use.

Tags:

Scala