Java Conventions – Is It Okay to Go Against All-Caps Naming for Enums?

conventionsenumjava

Several times I've seen people use title-case or even all lower-case naming for enum constants, for example:

enum Color {
  red,
  yellow,
  green;
}

This makes working with their string form simple and easy, if you want to do throw new IllegalStateException("Light should not be " + color + "."), for example.

This seems more acceptable if the enum is private, but I still don't like it. I know I can make an enum constructor with a String field, and then override toString to return that name, like this:

enum Color {
  RED("red"),
  YELLOW("yellow"),
  GREEN("green");

  private final String name;

  private Color(String name) { 
    this.name = name 
  }

  @Override public String toString() {
    return name; 
  }
}

But look how much longer that is. It's annoying to keep doing if you have a bunch small enums you want to keep simple. Is it okay to just use unconventional case formats here?

Best Answer

The short answer is, of course, whether you want to break with naming conventions for what are essentially constants... Quoting from the JLS:

Constant Names

The names of constants in interface types should be, and final variables of class types may conventionally be, a sequence of one or more words, acronyms, or abbreviations, all uppercase, with components separated by underscore "_" characters. Constant names should be descriptive and not unnecessarily abbreviated. Conventionally they may be any appropriate part of speech.

The long answer, with regards to use of toString(), is that's definitely the method to override if you want a more readable representation of the enum values. Quoting from Object.toString() (emphasis mine):

Returns a string representation of the object. In general, the toString method returns a string that "textually represents" this object. The result should be a concise but informative representation that is easy for a person to read. It is recommended that all subclasses override this method.

Now, I'm not sure why some of the answers drifted to talking about converting enums to-and-fro with String values, but I'll just give my take here as well. Such serialization of enum values can easily be taken care of by using either the name() or ordinal() methods. Both are final and thus you can be sure of the returned values so long as the names or positioning of the values do not change. To me, that's a clear-enough marker.

What I gather from the above is: today, you might want to describe YELLOW as simply "yellow". Tomorrow, you might want to describe it as "Pantone Minion Yellow". These descriptions should be returned from calling toString(), and I wouldn't expect either name() or ordinal() to change. If I do, that's something I need to resolve within my codebase or my team, and becomes a greater question than just an enum naming style.

In conclusion, if all you intend to do is to log a more readable representation of your enum values, I'll still suggest sticking to conventions and then overriding toString(). If you also intend to serialize them into a data file, or to other non-Java destinations, you still have the name() and ordinal() methods to back you up, so there's no need to fret over overriding toString().