import java.io.Serializable;
/**
* Enum example with unnecessary and ignored serialization specification
* details. The Enum is already Serializable and attempts to control its
* serialization behavior are ignored. See Section 1.12 ("Serialization of Enum
* Constants") of the "Java Object Serialization Specification Version 6.0".
*/
public enum StateEnum implements Serializable
{
ALABAMA("Alabama", "AL"),
CALIFORNIA("California", "CA"),
COLORADO("Colorado", "CO"),
IDAHO("Idaho", "ID"),
UTAH("Utah", "UT"),
WYOMING("Wyoming", "WY");
// Don't do this: Don't specify serialVersionUID for enums and don't use
// an arbitrary constant such as 42L for all versions; use serialver on Sun JDK
private static final long serialVersionUID = 42L;
private String stateName;
private String stateAbbreviation;
StateEnum(final String newStateName, final String newStateAbbreviation)
{
this.stateName = newStateName;
this.stateAbbreviation = newStateAbbreviation;
}
}
Because enums are automatically Serializable (see Javadoc API documentation for Enum), there is no need to explicitly add the "implements Serializable" clause following the enum declaration. Once this is removed, the import statement for the java.io.Serializable interface can also be removed. If you have any doubts about
Enum
being Serializable
, run the HotSpot-provided serialver tool against your favorite enum that does not declare itself Serializable
. The tool will return 0L
for all enums. When a class is not Serializable
, this tool returns the message "Class --yourClassNameHere-- is not Serializable." An example of this is shown in the next screen snapshot.The fact that serialver returns
0L
for the enum’s serialVersionUID
indicates that the enum is indeed Serializable
. The Javadoc also indicates this. A third way to prove this to yourself is to use instanceof
operator as shown in the next code sample.
import java.io.Serializable;
public class UsesStateEnum
{
private StateEnum state;
public UsesStateEnum(final StateEnum newState)
{
this.state = newState;
}
public StateEnum getState()
{
return this.state;
}
public void verifyEnumIsSerializable()
{
System.out.print("StateEnum instance of Serializable? ");
System.out.println(this.state instanceof Serializable ? "yes" : "no");
}
public static void main(final String[] arguments)
{
System.out.println("Verify Enum is Serializable");
final UsesStateEnum me = new UsesStateEnum(StateEnum.COLORADO);
me.verifyEnumIsSerializable();
}
}
As mentioned above, all Enums have a
serialVersionUID
of 0L
. Therefore, it is not necessary to specify one as is shown in the code above. In fact, when one is specified, it is ignored anyway. The example above intentionally used the hard-coded 42L used in Joshua Bloch’s Effective Java example of how not to create a serialVersionUID
. As the screen snapshot below indicates, this explicitly specified value is ignored anyway:The above screen snapshot also demonstrates an advantage of running serialver against a class to generate the
serialVersionUID
rather than making up an arbitrary long value such as 42L. By using the script, we get the 0L
result for all enums and improve our chances of remembering that enums all have 0L
for this value and don’t need it explicitly specified.Although it does not hurt anything to unnecessarily specify that an enum implements
Serializable
or to even provide an ignored serialVersionUID
, I prefer not to include these. One might argue that at least adding "implements Serializable" communicates the intent to have an enum be Serializable
, but my feeling is that this is a fundamental part of the language since J2SE 5 and such communication should be unnecessary. When building a class that needs to be Serializable
, using enum constituent pieces can be treated just the same as using Strings and primitives and the reference types corresponding to primitives.All of the details I demonstrated and explained in this blog posting related to Enums being inherently Serializable are concisely described in two paragraphs of Section 1.12 ("Serialization of Enum Constants") of the Java Object Serialization Specification.
Additional Resources
∞ Java Object Serialization Specification
∞ Serialization of Enum Constants
∞ Object Serialization: Frequently Asked Questions
∞ Into the Mist of Serialization Myths
∞ Flatten Your Objects: Discover the Secrets of the Java Serialization API
∞ Java Serialization Algorithm Revealed
1 comment:
You should also mention the ability to use custom serialization using the Externalizabe interface. This can speed up Serialization Overhead as I have shown in http://blog.dynatrace.com/2008/07/01/optimizing-remoting-by-optimizing-serialization/. Additionally you gain additional flexibilty for version upgrades as you are handling serialization on your own.
Post a Comment