Bits of Java – Episode 19: Java Enumerators

This week we are going to discuss Java enumerators. What are they? You can think of an enumerator as a way to define some special strings.

Suppose, for instance, you want to implement a method that takes as input parameter a color name and returns to you whether this color is a primary color or not. One way to do that is:


public boolean isPrimaryColor(String colorName) {
    switch(colorName) {
        case "YELLOW": case "BLUE": case "RED": return true;
        default: return false;
    }
}

Nothing too fancy, right? If the input parameter matches one of our primary colors we return true, otherwise we return false.

But, what if we accidentally forgot that we have used upper cases to define our colors and we pass as parameter red, in lower case? This does not match our first case, so it would end up to the default case of the switch, returning false. But red is a primary color as well as RED!

You could argue that it would be sufficient to add three more cases which return true, and which takes into account the possibility to pass a lower case string. Or, even better, you could simply substitute the switch(colorName) line with a switch(colorName.toUpperCase()) and you are done!

Well, then, what if a Spanish guy comes around and does not know that you chose English as language to define your colors? He could pass rojo as input parameter and still expects a true as an answer, but he will get false, instead.

You got the idea, right? Wouldn’t be better, if we had a way to define a series of possible values, of special strings, in such a way then this method could then take as input parameter just those values, instead of all possible strings?

Luckily, there is! Enumerators do exactly that! You can define an enumerator as a top-level element, as you do for a Java class.


public enum Colors {
    GREEN, BLUE, RED, PURPLE, YELLOW, PINK, BROWN, BLACK, WHITE
}

Now we have define an enumerator with all the colors we want to be allowed to be used. Our method, then, would become:


public boolean isPrimaryColor(Colors color) {
    switch(color) {
        case YELLOW: case BLUE: case RED: return true;
        default: return false;
    }
}

In this case there is not ambiguity when choosing how to pass the input parameter, because we cannot pass whatever String, but we have to pass a Colors value, which can only be one of those defined in the enumerator! Notice here, that in the case branches of the switch we did not put Colors.YELLOW , Colors.BLUE, etc, but just the value (YELLOW, BLUE, etc.)!

When working with enumerators, there are some useful methods you can profit of. For instance, if you want to list all the possible values of an enumerator, just use the values() method. This gives you an array of enumerator values, so it’s quite easy to loop over.


for(Colors c : Colors.values()) {
    System.out.println(c);
}

Every enumerator value gets a number, depending on the order in which they are defined. You can get it through the instance method ordinal(). While, to get the associated name, just use name().


Colors color = Colors.GREEN;
System.out.println(color.ordinal());//0
System.out.println(color.name());//GREEN

As you see, I initialized my variable color by statically accessing one of the enumerator value. I could have also used the static method valueOf() to initialize my variable from a String. Of course, this is a bit more risky, because, if you accidentally type a non existing value you would get a runtime exception!


Colors c1 = Colors.GREEN;
Colors c2 = Colors.valueOf("Green");//IllegalArgumentException!

You cannot, instead, initialize an enumerator by using a constructor. You can define constructors in an enumerator, but these are implicitly private, so they are not accessible from outside!

You can also define other things inside an enumerator, such as methods or fields. The important thing to remember is that the enumerator values have to be defined first, and, if other things are defined, then you have to put a ; after the last enumerator value.


public enum Colors {
    GREEN, BLUE, RED, PURPLE, YELLOW, PINK, BROWN, BLACK, WHITE; //remember the ;
    public Colors getFavouriteColor() {
        return GREEN;
    }
}

Last thing to remember is that an enumerator cannot be extended!

That’s all for enumerators in Java! As always, I hope you enjoyed the post and maybe learn something new! Next week we will discuss about Exception handling in Java!

by Ilenia Salvadori