-
-
Notifications
You must be signed in to change notification settings - Fork 143
Enumerations
Introduced in Jackson Scala Module 2.2
Enumerations in Scala can be tricky. The Scala documentation recommends declaring them in the form:
object Weekday extends Enumeration {
type Weekday = Value
val Mon, Tue, Wed, Thu, Fri, Sat, Sun = Value
}
This has two challenges to overcome:
-
Enumeration values have the Scala type of
Weekday#Value
, sinceValue
is an instance-scoped abstract class. However, JVM erasure reduces all of these to the same runtime type, and the type of the enclosing class is lost. -
Scala does not allow code to access the class of the singleton object instance at compile time;
classOf[Weekday.type]
does not compile. Type tricks have to be employed to construct a compile-time proxy.
Thankfully, you can refer to an object's type as a type parameter, so to handle this we rely on the TypeReference
class used in Jackson core. The difference is that normally you can create an anonymous derived class at runtime, but because an annotation needs a compile-type constant, we must create a named derived class to stand-in for the enumeration type Scala doesn't allow us to name:
class WeekdayType extends TypeReference[Weekday.type]
case class WeekdayHolder(@JsonScalaEnumeration(classOf[WeekdayType]) weekday: Weekday.Weekday)
The first line declares our TypeReference
proxy, to give the compiler a class it can refer to. The second line refers to the class instance in the new @JsonScalaEnumeration
annotation, to provide the information the Jackson Scala Module needs to locate the withName
method required to instantiate the enumeration value.
Versions of Jackson prior to 2.2 used a different serialization format for Enumerations that did not require an annotation. If the @JsonScalaEnumeration
is omitted, the serialized form of the above will look like
{"weekday":{"enumClass":"Weekday","value":"Fri"}}
The enumClass
field carries the necessary type information in the serialized form. It is expected this behavior will be deprecated in version 2.3, and removed entirely in 3.0.