Customizing Enums

by Dejan Bosanac

Enumerated types (enums) are a way to define fixed set of constants, so helpful in many areas of software development. In the most common case, in your Java code written for Java 5 or newer, you will use enums for int constants and replace chunks of code that look like this

    public static final int DIRECTION_NORTH     = 0;
public static final int DIRECTION_SOUTH = 1;
public static final int DIRECTION_EAST = 2;
public static final int DIRECTION_WEST = 3;


with something like this

public enum Direction {
NORTH, SOUTH, EAST, WEST;
}


Then, you'll change method definitions that look like

public void changeDirection(int direction) {
// do something
}


with something like this

 public void changeDirection(Direction direction) {
// do something
}


And finally, the method call will be changed too, from

ship.changeDirection(DIRECTION_EAST);


to

ship.changeDirection(Direction.NORTH);


There are a few obvious benefits from using enums over the standard int constants, such as the type safety and namespaces for example.

But we can also use enums to define other types of constants, string constants for example. You can often see examples of using enums to make a switch idiom for strings possible in Java. Take a look at the following example

        String direction = "WEST";
switch (Direction.valueOf(direction)) {
case WEST : System.out.println("Go west!");
break;
case EAST : System.out.println("Go east!");
break;
default : System.out.println("Go somewhere!");
}


It prints Go west! as a result which is great.

But in order to be truly useful for string constants purpose, enums needs some extra tuning and here's why.

4 Comments

Nick
2008-02-12 06:44:16
Thanks for the post Dejan...


We had been looking at ways of doing something similar with our enums. I will have to give this approach a shot in the future.


We actually use enums a lot of times for List of Values. And using the Enum instance name isn't always easy. For instance we have an Enum called CarType with TWO_DOOR and FOUR_DOOR. We don't want to display those strings to the user. So instead of doing like you have done, we actually attach strings to our Enums and call them messages.


public enum CarType {


TWO_DOOR("2 Door"),FOUR_DOOR("4 Door");


private String message;


CarType(String message){
this.message = message;
}


public getMessage() {
return this.message;
}
}


The advantage I see this way is we have more flexibility in our string. If you have a long string you want to display, your Enum instance name doesn't have to have a super long, capitalized, separated by underscores id. Another reason we have done this is for internationalization. We can put our i18n message key as the enum's message, and then when we display on our jsp's we can translate them.


Thanks again for your post...


-- Nick


Christian Ullenboom
2008-03-09 07:24:25
It's worth to mention that we can use a syntax known from anonymous inner classes as well:


public enum HttpHeader
{
IF_MODIFIED_SINCE() { @Override public String toString() { return "If-Modified-Since"; } },

USER_AGENT() { @Override public String toString() { return "User-Agent"; } },


UNKNOWN() { @Override public String toString() { return ""; } };


public static HttpHeader getValue( String value )
{
try
{
return valueOf( value.replaceAll( "-", "_" ).toUpperCase() );
}
catch ( Exception e )
{
return UNKNOWN;
}
}
}


Bye, Christian | tutego

Faisal
2008-05-01 01:06:43
This is superb article, Java is all in all Language.
Alvin
2008-05-28 05:22:37
Excellent contribution. Just a quick addition to mention that it is worth to mention that separating the enumeration from the name resolution can be very useful to integrate with ORM tools like Hibernate. I short example can be found at : Persisted enumerations in Hibernate