Help Recover a Post Thanks Lang!
Feb 24

We all know how to use enums - Ordinal values and even their textual names are now accessible. Heck, we can even iterate over all of them, eliminating the need of the old-fashioned C++ “START” and “END” values.

Enums are much more though. Java implements enums as full-fledged classes:

  • They have constructors, they have methods and they have fields.
  • They are treated specially in switch statements to make them more efficient.
  • They have special classes that allows enums to be used as bit-flags, and to be used efficiently when mapping values.

Enums as Classes

When you write a new enum, you are actually creating a class containing static instances of itself - The enum values. The class will extend the class Enum (discussed earlier for its weird generification), and every instance will be initialised with a String - the name of the enum value - and an integer - the enum’s ordinal value.
So, for example, the following enum:

enum CipherType {
  RSA,
  Blowfish;
}

Is in fact the equivilant of:

class CipherType extends Enum {
  public static final CipherType RSA = new CipherType(”RSA”, 0);
  public static final CipherType Blowfish = new CipherType(”Blowfish”, 1);

  private static final CipherType[] values = new CipherType[] { RSA, Blowfish };

  public static CipherType[] values() { return values.clone(); }
  public static CipherType valueOf(String name) { return Enum.valueOf(CipherType.class, name); }

  private CipherType(String name, int ord) {
    super(name, ord);
  }
}

Simple, isn’t it? The compiler does all of this for you. It’s just a regular class and instances, in every way. And as such, you can add methods to it, add fields to it, and then - Use them at your code for good measure. You can see how I used enums in my code as factory methods, and it’s not the only example at all. Almost any time you’d want to use a switch statement to perform something with a known set of parameters or determine a specific value, you could replace it with an enum method or field.

EnumSet and EnumMap

There are two classes provided with enums and for enums. The EnumSet class is implemented internally with a bit-vector, so that it’s a true flag. No more “and”s and “or”s - Use it like any other Set and it will do the hard work for you. For example, statements like if ((flag & SomeEnum.SomeValue) == SomeEnum.SomeValue) { .. } are replaced with the much more readable statement if (flag.contains(SomeEnum.SomeValue)) { .. }. Also, calls to methods where flags are required will use EnumSet.of(SomeEnum.SomeValue, SomeEnum.SomeOtherValue) instead of the awkward “or” semantic.

The second provided class is EnumMap and it uses an array and the automatically generated ordinal values of the enum to locate and store values according to these enums. This is a great boost to performance and every time you wish to map anything using an enum as key, you should use this class.

Performancing your switch statements

This is just being nit-picking, but for some it might be important. The switch statement is implemented under the hood in two ways: Either it is using an array as a table to locate the code to jump to according to the given value, or it uses a lookup table where it needs to search through a list of values, which is less efficient than the table. Because of that, the lookup table is used only when an array can’t be used, or in other words: When the values used for the cases are not sequential enough.

All that said, when enums are used in a switch statement, it’s their ordinal value that is being compared. That is, a table is always used for enums. So, if any of the previous paragraphs didn’t convince you to use enums yet, this really should!

Seriously now, I guess that’s what happens when you mess around with bytecode for fun.

Other posts of interest

3 Responses to “Tricks with Enums”

  1. Chaotic Java » Blog Archive » Whirling around Java Says:

    […] To implement the 24 Whirl commands I’ve used two enums (one for each wheel), each of them implementing the Command interface, which exposed one method of execute. This allowed me to write very short code (an enum name and a simple operation for execution, as they were all simple) and the compiler took care of generating 24 different classes for me. Then, the wheels could receive an array of the Command interface without knowing they are receiving an enum at all. Read back my tips with enums post for a refresh about them. […]

  2. Chaotic Java » Blog Archive » Enums & GWT Says:

    […] And that’s just unfortunate, because I really got used to using enums! Still, not having the syntax is not going to stop me. After all, enums in Java are eventually translated into classes, so I can just write my own GWT-compatible Enum-class. […]

  3. Switch by class type Says:

    […] language has done a great deal of removing boiler-plate code through means of compiler decisions: enums, strings and for-each loops are just a few of those. We could see something like the following for […]

Leave a Reply

Chaotic Java is Digg proof thanks to caching by WP Super Cache!