Sunday, June 02, 2013

Java Basics: Enum Types

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 in its Simplest Form:


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. 

Hope this Helps!
Please leave your comments.
Location: United States


Post a Comment