A Short Primer on Java Enums - part 1
In his JavaOne talk this year, Josh Bloch gave some very useful tips about using enums in Java. Here is my take on enums, and how to use them to represent simple value lists which would otherwise be stored in code tables. This document is in two parts - Part one covers the basics of Java enums, and Part 2 goes into more advanced use cases such as using enums with Hibernate.
Introducing Java enums
An enum represents a pre-defined list of static values. Most applications have lots of places where you need this sort of thing. Colours, states, font-styles - the list is endless. A common older approach (required before Java 5) was to define lists of static values is to use integer constants, as shown here:
public class Issue {
public static final int STATUS_OPEN = 1;
public static final int STATUS_CLOSED = 2;
public static final int STATUS_REOPENED = 3;
private int status;
public void setStatus(int status) {
this.status = status
}
...
}
However, this is a very poor solution, for many reasons, that Josh discusses in some detail in his Effective Java book. For example, there is no type safety. You can use any integer value in this field, which can result in errors, eg:
issue.setStatus(4); // This is wrong!
In addition, the solution is fragile. These values are integers, so they will be compiled into the classes that use them. Should you modify the int value associated with a particular constant, the client classes will not automatically recompile. And if the client classes are not recompiled, they will continue to use the old values, which will result in strange errors.
Luckely, in Java 5, you can use enums for a much more type-safe approach. An enum is basically a type-safe, pre-defined list of values, which you can define as follows:
public enum Status {
Open, Closed, Reopened
};
You can define an enum in the same way as you would a class. Enums that are used by many classes should be defined as public, stand-alone classes, defined in their own *.java file. Enums that are only used by a particular class, on the other hand should be defined as public inner classes, as shown here:
public class Issue {
public enum Status {
Open, Closed, Reopened
};
private Status status;
public Status getStatus() {
return status;
}
public void setStatus(Status status) {
this.status = status;
}
...
}
On of the great things about this is how typesafe it all is. You can use an enum like this as follows:
Issue issue = new Issue();
issue.setStatus(Issue.Status.Closed);
assertThat(issue.getStatus(), is(Issue.Status.Closed));
Here, you cannot fail to put a legal value into the status field, as it is verified by the compiler. For example, the following code, where we try to assign an Importance value to the Status field, simply won't compile:
Issue issue = new Issue();
activity.setStatus(Issue.Importance.Low); // This will not compile
Of course, if you use static imports, the code is even simpler:
import static com.mycompany.Issue.Status.Closed;
...
Issue issue = new Issue();
issue.setStatus(Closed);
Listing enum values
Now there are times that you might need to list the values in an enumaration. For example, you may want to create a list of entries in a SELECT element on an HTML page. You can do this with the static
values()method, as shown here:
ActivityStatus[] values = ActivityStatus.values();
for(ActivityStatus status : values) {
System.out.println(status);
}
This will produce the following list:
Open
Closed
Reopened
Easy! Note that the enum values are displayed in their natural order (their order of appearance in the Java class), not in alphabetical order. This means you can define an implicit order, and not worry about having to add an extra field to define the order manually.
Conclusion
So now, we've covered some of the basic uses of enums. In the next part of this article, we will look at more advanced uses of enums, such as how they integrate with Hibernate.
John is a freelance consultant specialising in Enterprise Java, Web Development, and Open Source technologies, currently based in Wellington, New Zealand. Well known in the Java community for his many published articles, John helps organisations to optimize their Java development processes and infrastructures and provides training and mentoring in open source technologies, SDLC tools, and agile development processes. John is principal consultant at Wakaleo Consulting, and runs several Training Courses on open source Java development tools and best practices. John is a DZone MVB and is not an employee of DZone and has posted 57 posts at DZone. You can read more from them at their website.
- mr_john_smart's blog
- Login or register to post comments
- 3499 reads
- Printer-friendly version
(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)










Comments
nitin pai replied on Mon, 2008/05/19 - 11:47am
Mwanji Ezana replied on Tue, 2008/05/20 - 6:04am
You could declare a valueOfInRange(int) kind of method on the enum, which would find the enum corresponding to the value you passed in (take a look at the default valueOf() method). e.g.:
STATUS.valueOfInRange(12) would return STATUS1
STATUS.valueOfInRange(23) would return STATUS2
You'd have to decide what to do with 20, which currently belongs to both instances (or maybe that's just a typo?).