Ref: Effective Java by Joshua Bloch
Here is how it looks in its simplest enum form.
The basic idea behind Java's enum types is simple: they are classes that export one instance for each enumeration constant via a public static final field. Enum types are effectively final, by virtue of having no accessible constructors. They are generalization of singleton.
Let's go on with richer enum forms with methods and fields. For a nice example of a rich enum type, consider the eight planets of our solar system. Each planet has a mass and radius, and from these two attributes youcan compute its surface gravitiy.
Enums are by their nature immutable, so all fields should be final.
While the Planet enum is simple, it is surprisingly powerful. Note that Planet, like all enums, has a static values method that returns an array o fits values in the order they were declared. Note also that the toString method returns the declared name of each enum value.
The technique demonstrated in the Planet example are sufficient for most enum types, but sometimes you need to associate fundamentally different behavior with each constant. One way to achieve this is to switch on the value of the enum.
This code works but it isn't very pretty. Consider below powerful side of Enum, implementing abstract method in each Enum instance
If you add a new constant to the second version of Operation, it is unlikely that you'll forget t oprovide an apply method, as the method immediately follows each constant decleration.
So when should you use enums? Anytime you need a fixed set of constants. Of course, this includes "natural enumerated types" such as planets, the days of the week, and the chess pieces, but it also includes other sets for which you know all the possible values at compile time such as choices on a menu, operation codes etc.