Do you know Java: Less known side of Enums


Enums are easy and straigthforward at first sight, but this type has some hidden sides.

public enum Day {
    MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}
  1. For enumeration type, Java has a keyword called enum.
  2. That was introduced in Java 1.5.
  3. All enum types are implicitly inhereted from Enum class.
    • Hence, all enum types has all methods that Enum has, like name, ordinal, etc.
    • We cannot extend an enum, and enum does not extend custom types.
  4. Enums constructor is not callable.
  5. Though, it is not callable,
    • enum has custom constructor,
    • constructor can be overridden,
    • constructor has to be package-private or private.
  6. Enums can be used in switch statement.
  7. Enumeration values have an ordinal which represents its place in the enumeration, like an index.
  8. All enums are comparable, since Enum implements Comparable interface, and compareTo is based on ordinal.
  9. Two instances of an enum are always equivalent according to == and equals as well.
  10. All methods except toString are final in Enum.
    • Cannot override them in our custom enumeration type.
  11. To get all values (instances) of an enum, we can use a static method, called values.
    • Not documented.
    • Gives values in the same order as they are declared.
  12. Recommended way to get a value based on String is Enum.valueOf
    • valueOf(String): T method is also not documented, just mentioned in documentation of Enum.

Different type of enums

Empty

public enum Empty {

}

System.out.println(Empty.values().length); // => 0

With Instances

public enum Level {
    DEBUG, INFO, WARN, ERROR, FATAL //;
}

Semicolon (;) is optional if enum does not have anything else just instances.

With Method

public enum Level {
    DEBUG, INFO, WARN, ERROR, FATAL; 

    public void print() {
        // ...
    }
}

Here, semicolon is required at the end of the instances.

Order of Instances

Order of instances are not important except one depends on another.

public enum NextOne {
    A(B), B(C), C(A);

    private NextOne next;

    NextOne(NextOne next) {
        this.next = next;
    }
}

Compiler cannot inference that object B is an instance of NextOne. That means the above code cannot compile.

Methods overriding

public enum Day {
    MONDAY {
        @Override
        public String toString() {
            return "Just another manic Monday.";
        }
    }, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY;
}

Further custom methods are also accepted in the block.

Abstract methods

enum can be extended with abstact methods, though we have to implement it in the instances.

enum also can implement interfaces.

Annotation

We can place annotations on it.

@Author(name = "jancsi")
public enum Day {
    // ...
}

Better way than valueOf

As I have experienced, valueOf is far not the right method to get an enum instance based on String. Its drawback is valueOf throws IllegalArgumentException.

Here is what I use if it is needed. It returns null if String param does not match.

public Day from(String value) {
    for (Day day : Day.values()) {
        if (day.name().equalsIgnoreCase(value)) {
            return day;
        }
    }
    return null;
}

from, parse also a good name! Use meaningful names!

In this post we have seen some less known features of enums.

Documentation about enums are here.

Code can be found: https://github.com/torokmark/do-you-know-java