Click here to Skip to main content
Click here to Skip to main content

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

By , 17 May 2011
 

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:

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:

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:

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:

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:

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:

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)

About the Author

Nagy Vilmos
President Belligerent Bad Tempered Old Fools Club
United Kingdom United Kingdom
Member
Do not tell anyone I am not Hungarian. It's a huge secret.
I have worked across too many platforms over the years - COBOL, Pascal, C, C++, VB3-6, C# and java are some of them - and now I just write pretty front ends for users with less wit than a gumby.
 
If I had a pound for everything I've learned over the years, I'd have £12,879.73
 
Semper ebrius, quantum variat.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralMy vote of 5memberMarco Bertschi4 Mar '13 - 4:53 
Fine one, finally found something where I can start with a multilang enum.
GeneralMy vote of 5memberPhat (Phillip) H. VU3 Jan '13 - 17:13 
Nice.
GeneralMy vote of 5memberEnrique Albert17 Dec '12 - 10:07 
Years working with Enums and never realized. Good article. Thanks
GeneralRe: My vote of 5memberNagy Vilmos17 Dec '12 - 22:02 
Thank you, it's always nice to receive positive feed back.


Panic, Chaos, Destruction. My work here is done.
Drink. Get drunk. Fall over - P O'H
OK, I will win to day or my name isn't Ethel Crudacre! - DD Ethel Crudacre
I cannot live by bread alone. Bacon and ketchup are needed as well. - Trollslayer
Have a bit more patience with newbies. Of course some of them act dumb - they're often *students*, for heaven's sake - Terry Pratchett

GeneralI think you mean EnumerationmemberPIEBALDconsult6 Jul '12 - 5:42 
I think you mean "Enumeration".
GeneralMy vote of 5memberaprNgp22 Dec '11 - 18:53 
A very good article. Thanks.
GeneralMy vote of 5memberGuyThiebaut12 Oct '11 - 11:03 
Well explained article - I used enums in other languages and had not used them up till now in C#, so I think I will start using them.
 
Thanks!
GeneralJust a thoughtmemberBalboos17 May '11 - 4:23 
By and large, your enum's have evolved into classes.
 
Being old-school (C, then C++), I still have this view of an enum, being short for enumeration, is a mapping of (numeric) values to numbers.
 
With the coming of C#, the enum's capabilites have expanded greatly - but are we not losing sight of it's intended purpose? Was not the purpose to give an enhanced readability by substituting readily understood text for (integer) values? Maybe a little bit of implicit behavior?*
 
This last questions are not intended as criticism, but rhetorical questions which I will ask myself, as well. One can take an enumeration to new places - but do we really want to go there in that way, converting them to Classes with structured data objects and methods?
 

Cogitating.
 

 

 

eg. enum { TEA, COFFEE, COCOA, BEV_COUNT };
eg. enum { TEA, COFFEE, COCOA, TEQUILA, BEV_COUNT }; // BEV_COUNT still serves its intended purpose

 

"The difference between genius and stupidity is that genius has its limits." - Albert Einstein
"As far as we know, our computer has never had an undetected error." - Weisert
"If you are searching for perfection in others, then you seek disappointment. If you are seek perfection in yourself, then you will find failure." - Balboos HaGadol Mar 2010

GeneralRe: Just a thoughtmemberNagy Vilmos17 May '11 - 21:59 
In Java, enums are not numbered unless implicitly made so. Each value is an object representing one of the finite states.


Panic, Chaos, Destruction.
My work here is done.

 
or "Drink. Get drunk. Fall over." - P O'H
 
OK, I will win to day or my name isn't Ethel Crudacre! - DD Ethel Crudacre
 
Have a bit more patience with newbies. Of course some of them act dumb -- they're often *students*, for heaven's sake. -- (Terry Pratchett, alt.fan.pratchett)

AnswerRe: Just a thoughtmemberBalboos18 May '11 - 1:29 
My thoughts are not base upon what enums currently are so much is should they have gone there.
 
As more and more capabilities are enabled, the actually utility (from their progenitor languages, C/C++) vs. a class becomes obscured. They originally served as what I will roughly call dynamic value MACRO definitions.
 
Switch statements (for example) could only handle integers, so, borrowing from your article, one could create an
enum Seasons { SUMMER, FALL, WINTER, SPRING} and use them in the switch. The readability increase is tremendous (and thus the chance for errors reduced). Changing to enum Seasons { FALL, SUMMER, WINTER, SPRING} would not break your code, nor would enum Seasons { FALL=1,AUTUMN=1, SUMMER, WINTER, SPRING} (although I think this last could add inconsistency and eventual confusion).
 
In current usage (e.g., .NET), there are a plethora of enums of this type for defining colors, types, etc.
 
So, OK, Java gives them super-powers. Does this now actually obscure their purpose - making them more of a redundancy with respect to a class ? Enum's were, implicitly integer lists. If we expand them to floats, does that diminish them (for now, each member needs to be defined, unless whole numbers, and then we could have used a cast IF needed). Using an enum for a string mapping is (visually) redundant (a string mapped to an alias string). So - then you add methods and, well, why not just use a class?
 
What comes to mind is an app I was writing with someone else (I rarely do this) - and had to explain what a structure was and why I used it instead of a class. It was C#, and other then default public vs. default private, the differences were not very convincing when I needed to verbalize it.
 
So - a synopsis of what disturbs me is that more varied object creations are picking up one another's attributes. This could be extrapolated to everything doing everything . . . then one fine day, a new version of will come out deprecating all but one of them and the simple, precise, convenient, and lean tools will be gone.
 
So, I need to consider my thoughts for evaluation of this evolution.
 

 
One other thing: you wrote
Nagy Vilmos wrote:
enums are not numbered unless implicitly made so
- I presume you meant 'explicitly'
 

 


"The difference between genius and stupidity is that genius has its limits." - Albert Einstein
"As far as we know, our computer has never had an undetected error." - Weisert
"If you are searching for perfection in others, then you seek disappointment. If you are seek perfection in yourself, then you will find failure." - Balboos HaGadol Mar 2010

GeneralRe: Just a thoughtmemberNagy Vilmos24 May '11 - 5:11 
In Java, enums are not designed to behave as numbers. The design was to use explicit objects with no inherent numerical values and the order of enums is based on their position in the list.


Panic, Chaos, Destruction.
My work here is done.

 
or "Drink. Get drunk. Fall over." - P O'H
 
OK, I will win to day or my name isn't Ethel Crudacre! - DD Ethel Crudacre
 
Have a bit more patience with newbies. Of course some of them act dumb -- they're often *students*, for heaven's sake. -- (Terry Pratchett, alt.fan.pratchett)

GeneralRe: Just a thought - Java enum instances have an order numbermembervulcan_29 Aug '11 - 22:52 
You guys are both right, but there are mitigating circumstances so there is hope our readers will forgive. Poke tongue | ;-P
 
Java enums DO have implicit integer values associated with each instance in the enum; the first definition gets 1 (or was it zero? pretty sure it starts with one), the second gets ordinal 2 etc. You can obtain this "hidden" value using the ordinal() method of the enum base class so int index = SUMMER.ordinal(); // gives 2
 
The C++ feature of value assignment:
enum seasons ( spring=1, summer=1, ... };
 
is achieved in Java enums by
enum seasons{
int index = 0;
 
SPRING( 1 );  PRINTEMPS( 1);
SUMMER( 2 ); ETE( 2 ) ;
SPRING( 3 ); LAUTUM( 3 );
SUMMER( 4 );  LHIVER( 4 );
 
// contructor
private seasons( int input )
  { this.index = input; }
 
public getIndex()
   { return index; }
}
 
and no, my code is not syntactically correct so don't bother nagging about it.
 
I can understand the desire to keep the simple "limited list of values" meaning of the enum, but having used the java enum to implement a state machine, to process tuple data in 3D animation plug-ins and a host of other applications i can tell you the Java enum rocks. To have any amount of data and/or behavior attached to the instances of an enum is a very powerful way to simplify ones programming.
 
long live the java enum!!

GeneralRe: Just a thought - Java enum instances have an order numbermemberaprNgp22 Dec '11 - 18:59 
The index starts with 0 in JAVA
http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Enum.html#ordinal%28%29[^]
Apurv
 
If Java had true garbage collection, most programs would delete themselves upon execution.

GeneralRe: Just a thought - Java enum instances have an order numbermemberNagy Vilmos16 Jan '12 - 23:00 
An important point here is that you can change the order in which the enum items occur, that is change there index, but the items are unchanged.
For example, take our simple seasons:
enum Season {
    SPRING,
    SUMMER,
    AUTUMN,
    WINTER;
}
I would always persist these by their string values, then if we decided to reorder the list:
enum Season {
    WINTER,
    SPRING,
    SUMMER,
    AUTUMN;
}
There is no change of meaning. In Java we can access the current position using ordinal() and retrieve them using values()[], but that is just referencing the array they are held in rather than any real property of the items.


Panic, Chaos, Destruction. My work here is done.
Drink. Get drunk. Fall over - P O'H
OK, I will win to day or my name isn't Ethel Crudacre! - DD Ethel Crudacre
I cannot live by bread alone. Bacon and ketchup are needed as well. - Trollslayer
Have a bit more patience with newbies. Of course some of them act dumb - they're often *students*, for heaven's sake - Terry Pratchett

GeneralnicememberCIDev17 May '11 - 3:04 
A nice little intro to enums Smile | :)
Just because the code works, it doesn't mean that it is good code.

GeneralMy vote of 5memberRhuros17 May '11 - 2:29 
Nice article...
GeneralMy vote of 5memberChris Meech17 May '11 - 2:18 
Great Java work. But your weather forecasting skills leave a bit to be desired. Smile | :)
GeneralMy vote of 5mvpLuc Pattyn17 May '11 - 2:14 
You still haven't figured the proper order of the seasons, have you?
 
Big Grin | :-D
GeneralMy vote of 5memberTorstenH.17 May '11 - 2:08 
good article - it describes pretty well & simple how to use them
GeneralMy Enum TipmemberDaveAuld17 May '11 - 2:01 
http://www.codeproject.com/Tips/160838/Quick-And-Dirty-Option-Lists-using-Enums.aspx[^]
 
Handy for building option lists!
Dave
Find Me On: Web|Facebook|Twitter|LinkedIn

Folding Stats: Team CodeProject

Generalcan we write classes in an enum ?memberDevUK17 May '11 - 2:00 
i tried your code and it didnt work, plus, it'd be nice if you attach a downloadable sample
GeneralRe: can we write classes in an enum ?memberNagy Vilmos17 May '11 - 2:22 
I will add some example code shortly. What I published has been tested and should run, what was the problem?


Panic, Chaos, Destruction.
My work here is done.

 
or "Drink. Get drunk. Fall over." - P O'H
 
OK, I will win to day or my name isn't Ethel Crudacre! - DD Ethel Crudacre
 
Have a bit more patience with newbies. Of course some of them act dumb -- they're often *students*, for heaven's sake. -- (Terry Pratchett, alt.fan.pratchett)

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

Permalink | Advertise | Privacy | Mobile
Web02 | 2.6.130523.1 | Last Updated 17 May 2011
Article Copyright 2011 by Nagy Vilmos
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid