Sunday, June 02, 2013

JDK 1.5 a.k.a Tiger release marked
the addition of two new reference types into the language. A special Kind Class
called Enum Types and a new kind of interface called an annotation Types.

In this blog post we will discuss about
the Enum Types and how it is better than the existing approach int and String Enum
pattern that many of us used or may still be using in (pity on programmers as
they are missing out better approach to handle things and making the project
fragile in long run) there projects.

Note: Enum has been made a
reserved keyword in 1.5 migrating your existing project on JDK 1.5 might break
your existing code if anywhere you have used enum as a variable name.

An Enum allows a programmer to define
fixed set of named constants such as the planets in the Solar System, Suits in
the deck of playing cards or Days in a Week.

Points to Remember:

1. Enum Types over a period of time
can evolve into a full-fledged abstraction.

2. Enum Types are by nature
immutable, so all fields should be marked final they can be public but it’s
better to make them private and provide them public accessors.

3. Before Enum Types a common int and
String Enum pattern was used by the programmer which has many shortcomings.

Before JDK 1.5 – Existing int Enum
Pattern

public static final int Day_SUNDAY = 0;

public static final int Day_MONDAY = 1;

public static final int Day_TUESDAY = 2;

…..

Shortcomings in above approach:

No
Type Safety: Your compiler without warning you will compile even if you pass
any int value instead of the predefined set of values.

No
Namespace: You must prefix constants (in this case Day_) to avoid any
confusion/collisions in case you introduce a new pattern in your project in
future.

Fragile:
As int Enum pattern are compile-time constants, they are compiled in the files
those uses them. It requires recompilation of all those files that uses them if
any changes made to them else it will result in unexpected behavior.

Uninformative:
These patterns won’t allow you to carry any addition details printing them will
not tell you more than what value each of them are assigned even the type is
not known whether it’s a int or a String. Even the iteration over all the
declared values is not possible and there is no way to find out the exact no.
of declared constants.

Enum Types not only overcomes the
above mentioned shortcomings in the existing approach but adds much more
functionality that one can expect from it. Many programmers are aware of Enum
Types even before they were introduced in JDK 1.5 due to its presence in
languages like C/C++. They look similar to their counterparts in other
languages (i.e., in C/C++ or C#) where they are just fancy int values whereas Java
Enum Types are Real Java Classes and are much more powerful thanks to the
Compiler which makes it possible under the hoods with no burden on programmers.

Enum Types are final by virtue,
having no accessible Constructor and hence are purely instance-controlled. Enum
Types cannot be extended, and an Enum Type cannot extend other class or enum as
all Enum Types are subclasses of java.lang.Enum maintaining the single level
inheritance but all Enum Types can implement interfaces.

Enum Types can either defined as
Top-Level full-fledged class or it can be nested static member in another
reference types.

Enum Provides Type Safety: You can
assign an Enum one of the defined constant otherwise Complier Error is thrown.

Comparison: Comparing Enum Types
using == or equals() will be same.

Informative: Each Enum Constant
can override if required the toString() to provide any information they want.

Namespaces: Constants with same
name can exist as all constants can be accessed using the Enum name which
cannot be same.

No Need to Recompile: As Enum
Types are not compiled into the classes which use them, so we can add/remove or
reorder any enum constant without compiling all the files that uses it.

You can define fields or methods
in an Enum Types as you do in a Regular Java Class.

With Enum Types the order in which
you define the fixed set of named constants matter a lot.

Java.lang.Enum overrides methods
from Object class and made a few of them final and it also implements
interfaces like Comparable and Serializable that handles Comparison and
Serialization for you automatically.

Enum can be a Top-Level Class or if
it’s defined inside a Top-Level Class then it acts as a static member class of
that Top-Level Class.

Inside an Enum Type you can
declare an abstract method in that case we have to @Override the abstract
method with a concrete one for each named constant using Constant-Specific
Class Body. Such methods are known as Constant-Specific Method Implementations.

The toString() method in its
default form will return the Constant Name which is same as calling the name()
method but as toString() method is not final it can be Overridden either for
whole Enum in which case every Constant will share the same value or it can be
Overridden for a few if not all as well that way an Enum Types achieves
Polymorphism like any Regular Java Class.

Iteration and Size of Enum can be
known using the values() method. The values() method return an Array which you
can use to iterate and using the length variable its size can be easily known.

As mentioned before Order in which the
Constants are defined is very important as whenever the constants are iterated
it can be iterated in the order it’s defined in the Enum.

ordinal() method returns an
integer indicating the index at which the constant is placed.

I will update this post with more information and examples. EnumSet and EnumMap later.