Helping ordinary people create extraordinary websites!
GET OUR NEWSLETTER
Your Email:
 

Getting Started with Enumerated Types

By Brett McLaughlin
2005-04-22


Working with Enumerated Values

The examples you've seen so far have been rather simple, but enumerated types offer much more. Enumerated values, which you can iterate over and use in switch statements, among other things, are very valuable.

Iterating over enums
Let's begin with an example that shows how to run through the values of any enumerated type. This technique, shown in Listing 4, is handy for debugging, quick printing tasks, and loading enums into a collection (which I'll talk about shortly):

Listing 4. Iterating over enumerated values

public void listGradeValues(PrintStream out) throws IOException {

for (Grade g : Grade.values()) {
out.println("Allowed value: '" + g + "'");
}
}
Running this snippet of code will give you the output shown in Listing 5:

Listing 5. Output of iteration
Allowed Value: 'A'

Allowed Value: 'B'
Allowed Value: 'C'
Allowed Value: 'D'
Allowed Value: 'F'
Allowed Value: 'INCOMPLETE'
There's a lot going on here. First, I'm using Tiger's new for/in loop (also called foreach or enhanced for). Additionally, you can see that the values() method returns an array of individual Grade instances, each with one of the enumerated type's values. In other words, the return type of values() is Grade[].

Switching on enums
Being able to run through the values of an enum is nice, but even more important is the ability to make decisions based on an enum's values. You could certainly write a bunch of if (grade.equals(Grade.A))-type statements, but that's a waste of time. Tiger has conveniently added enum support to the good old switch statement, so it's easy-to-use and fits right in with what you already know. Listing 6 shows you how to pull this off:

Listing 6. Switching on enums

public void testSwitchStatement(PrintStream out) throws IOException {

StringBuffer outputText = new StringBuffer(student1.getFullName());

switch (student1.getGrade()) {
case A:
outputText.append(" excelled with a grade of A");
break;
case B: // fall through to C
case C:
outputText.append(" passed with a grade of ")
.append(student1.getGrade().toString());
break;
case D: // fall through to F
case F:
outputText.append(" failed with a grade of ")
.append(student1.getGrade().toString());
break;
case INCOMPLETE:
outputText.append(" did not complete the class.");
break;
}

out.println(outputText.toString());
}
Here the enumerated value is passed into the switch statement (remember, getGrade() returns an instance of Grade) and each case clause deals with a specific value. That value is supplied without the enum prefix, which means that instead of writing case Grade.A you need to write case A. If you don't do this the compiler won't accept the prefixed value.
You should now understand the basic syntax involved in using switch statements, but there are still a few things you need to know.

Planning ahead with switch
You can use the default statement with enums and switches, just as you would expect. Listing 7 illustrates this usage:

Listing 7. Adding a default block

public void testSwitchStatement(PrintStream out) throws IOException {

StringBuffer outputText = new StringBuffer(student1.getFullName());

switch (student1.getGrade()) {
case A:
outputText.append(" excelled with a grade of A");
break;
case B: // fall through to C
case C:
outputText.append(" passed with a grade of ")
.append(student1.getGrade().toString());
break;
case D: // fall through to F
case F:
outputText.append(" failed with a grade of ")
.append(student1.getGrade().toString());
break;
case INCOMPLETE:
outputText.append(" did not complete the class.");
break;
default:
outputText.append(" has a grade of ")
.append(student1.getGrade().toString());
break;

}

out.println(outputText.toString());
}
Consider the code above and realize that any enumerated value not specifically processed by a case statement is instead processed by the default statement. This is a technique you should always employ. Here's why: Suppose that the Grade enum was changed by another programmer in your group (who of course forgot to tell you about it) to the version shown in Listing 8:

Listing 8. Adding values to the Grade enum

package com.oreilly.tiger.ch03;


public enum Grade {
A, B, C, D, F, INCOMPLETE,
WITHDREW_PASSING, WITHDREW_FAILING
};
Now, if you used this new version of Grade with the code in Listing 6, these two new values would be ignored. Even worse, you wouldn't even see an error! In these cases, having some sort of general purpose default statement is very important. Listing 7 may not handle these values gracefully, but it will give you some indication that values have snuck in, and that you need to address them. Once you've done that you'll have an application that continues to run, doesn't ignore values, and that even even instructs you to take later action. Now that's good coding.

Tutorial Pages:
» Represent Constants in a Typesafe Manner Using Java 5.0
» Defining an Enum
» Working with Enumerated Values
» Enums and Collections
» Going Further
» Use Them, But Don't Abuse Them
» Resources


First published by IBM developerWorks


 | Bookmark
Related Tutorials:
» All about JAXP, Part 1
» Make Database Queries Without the Database
» Load List Values for Improved Efficiency
» 2 Ways To Implement Session Tracking
» A Simple Way to Read an XML File in Java
» Develop Aspect-Oriented Java Applications with Eclipse and AJDT

Advertise with Us!


Tutorials Scripts Web Hosting Developer Manuals
Resources