Click here to Skip to main content
15,844,152 members
Articles / Programming Languages / Java / Java SE

The Secret Classes or How I Stopped Counting and Loved the Enumerator

Rate me:
Please Sign up or sign in to vote.
4.92/5 (35 votes)
17 May 2011CPOL3 min read 50K   48   22
A look at how to use the enum in Java.

Introduction

This article will examine some of the uses that the enum type can be put to. I don't know about you, but I like using enumerators. The perceived usage of the enum type is that they provide a list of possible values and are required for the switch statement. That's it, right? Big wrong.

The enum type is a class. By remembering this, the extensibility of an enum is great. It can be used for a whole lot more than simply representing the fixed values for an attribute.

It's Objects All the Way Down

I'll start with a simple premise. An enum type defines a class that has a fixed number of instances. Like any class, there can be member variables and methods giving the whole Java world in a simple structure. Let's look at a simple example:

Java
public enum Season
{
   SUMMER,
   WINTER,
   AUTUMN,
   SPRING
}

Here is a class, called Season, that has four fixed instances. It's important to remember this, as the fact that you have four objects is what gives the enum its simple structure and its amazing power. Power it is sworn to use for good.

A common use of enums is in switch statements such as this:

Java
String getForcast(Season season)
{
  switch (season)
  {
     case SUMMER:
     {
        return "Sun, sun, sun";
     }
     case AUTUMN:
     {
        return "Cold and blustery";
     }
     case WINTER:
     {
        return "Snow and ice";
     }
     case SPRING:
     {
        return "Overcast with showers";
     }
  }
  return null;
}

"Hang on! The elements of the enumerator are all objects so can't they just have a method to return the forecast?" I hear you cry. Good spot. That is exactly the way to go. A member variable, a method, and a simple constructor, and off you go:

Java
public enum Season {
   SUMMER("Summer", "Sun, sun, sun"),
   WINTER("Winter", "Snow and ice"),
   AUTUMN("Autumn", "Cold and blustery"),
   SPRING("Spring", "Overcast with showers");

   private final String seasonName;
   private final String forcast;
   private Season(String seasonName, String forcast)
   {
      this.seasonName = seasonName;
      this.forcast = forcast;
      System.out.println("Creating " + this);
   }
   String getForcast()
   {
      return this.forcast;
   }

   public String toString()
   {
      return seasonName + "{" + forcast + '}';
   }
}

I've included a friendly string description and overridden the method toString().

Now, instead of having to write a method outside of Season that takes a value as an argument, the values can be invoked directly to get the value:

Java
String forcast = Season.WINTER.getForcast();

The Immutible Likeness of Being [An Enumeration]

If you're observant, the member variables are both marked final. This is not mandated but, and it's a big Jo-Lo one, it is definitely encouraged.

So each enumeration is an object and it can have variables, methods, the whole low-flying acrobatics team. These are not just objects, their special status means they must be treated as immutable objects. They're not quite immutable but it is a good perspective to take.

By being an enum, there is no need for the hashCode() and equals() methods. Each instance is unique and its equality is fixed. Because of this nature, it is recommended that you don't change their states.

You Want Functionality With That?

I've shown above the way that enum objects can have properties and methods. Sometimes the behaviour of an action must differ depending on the value of the enum. This can be achieved with an abstract method that is overridden by each enum or by having a functional class provide the behaviour.

The abstract method first:

Java
public enum Season
{

   SUMMER("Summer", "Sun, sun, sun")
   {
      boolean willItRain()
      {
         return false;
      }
   },
   //...
   SPRING("Spring", "Overcast with showers")
   {
      boolean willItRain()
      {
         return true;
      }
   };

   //...

   abstract boolean willItRain();
}

This works but it isn't that extensible, and the enumeration class soon becomes clogged if you have just a few of the overrides. It is time to delegate the work to a functional class; enter the enumeration factory method.

We first move all the forecasting out of the enum class. We have a base, SeasonFunctions, that is abstract, and then four lovely children that can implement the functionality anyway they see fit:

Java
abstract class SeasonFunctions {
   private final String seasonName;
   private final String forcast;

   SeasonFunctions(String seasonName,
         String forcast)
   {
      this.seasonName = seasonName;
      this.forcast = forcast;
      System.out.println("Creating " + this);
   }
   abstract boolean willItRain();
   abstract int dayTimeHigh();
   abstract int nightTimeLow();

      String getForcast()
   {
      return this.forcast;
   }

   public String toString()
   {
      return "SeasonFunctions{" + this.getSeasonName()  + "}";
   }

   String getSeasonString()
   {
      return this.getSeasonName() + "{" + this.getForcast() + '}';
   }

   private String getSeasonName()
   {
      return this.seasonName;
   }
}

History

Initial submission - more to come.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
President Belligerent Bad Tempered Old Fools Club
United Kingdom United Kingdom
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralMy vote of 5 Pin
Marco Bertschi4-Mar-13 5:53
protectorMarco Bertschi4-Mar-13 5:53 
GeneralMy vote of 5 Pin
WebMaster3-Jan-13 18:13
WebMaster3-Jan-13 18:13 
GeneralMy vote of 5 Pin
Enrique Albert17-Dec-12 11:07
Enrique Albert17-Dec-12 11:07 
GeneralRe: My vote of 5 Pin
Nagy Vilmos17-Dec-12 23:02
professionalNagy Vilmos17-Dec-12 23:02 
GeneralI think you mean Enumeration Pin
PIEBALDconsult6-Jul-12 6:42
mvePIEBALDconsult6-Jul-12 6:42 
GeneralMy vote of 5 Pin
AprNgp22-Dec-11 19:53
AprNgp22-Dec-11 19:53 
GeneralMy vote of 5 Pin
GuyThiebaut12-Oct-11 12:03
professionalGuyThiebaut12-Oct-11 12:03 
GeneralJust a thought Pin
W Balboos, GHB17-May-11 5:23
W Balboos, GHB17-May-11 5:23 
GeneralRe: Just a thought Pin
Nagy Vilmos17-May-11 22:59
professionalNagy Vilmos17-May-11 22:59 
AnswerRe: Just a thought Pin
W Balboos, GHB18-May-11 2:29
W Balboos, GHB18-May-11 2:29 
GeneralRe: Just a thought Pin
Nagy Vilmos24-May-11 6:11
professionalNagy Vilmos24-May-11 6:11 
GeneralRe: Just a thought - Java enum instances have an order number Pin
vulcan_29-Aug-11 23:52
vulcan_29-Aug-11 23:52 
GeneralRe: Just a thought - Java enum instances have an order number Pin
AprNgp22-Dec-11 19:59
AprNgp22-Dec-11 19:59 
GeneralRe: Just a thought - Java enum instances have an order number Pin
Nagy Vilmos17-Jan-12 0:00
professionalNagy Vilmos17-Jan-12 0:00 
Generalnice Pin
BillW3317-May-11 4:04
professionalBillW3317-May-11 4:04 
GeneralMy vote of 5 Pin
Rhuros17-May-11 3:29
professionalRhuros17-May-11 3:29 
GeneralMy vote of 5 Pin
Chris Meech17-May-11 3:18
Chris Meech17-May-11 3:18 
GeneralMy vote of 5 Pin
Luc Pattyn17-May-11 3:14
sitebuilderLuc Pattyn17-May-11 3:14 
GeneralMy vote of 5 Pin
TorstenH.17-May-11 3:08
TorstenH.17-May-11 3:08 
GeneralMy Enum Tip Pin
DaveAuld17-May-11 3:01
professionalDaveAuld17-May-11 3:01 
Generalcan we write classes in an enum ? Pin
DevUK17-May-11 3:00
DevUK17-May-11 3:00 
GeneralRe: can we write classes in an enum ? Pin
Nagy Vilmos17-May-11 3:22
professionalNagy Vilmos17-May-11 3:22 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.