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 Javabook. 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.