Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java enum - why use toString instead of name

Tags:

java

enums

People also ask

What does toString on an enum do?

toString(). The toString() method calls the name() method which returns the string representation of the enum constant. In listing 1, the value returned by calling the name() and toString() on an Animal.

Can enum have toString?

The Java Enum has two methods that retrieve that value of an enum constant, name() and toString(). The toString() method calls the name() method, which returns the string representation of the enum constant.

Why do we use toString method in Java?

The toString method is used to return a string representation of an object. If any object is printed, the toString() method is internally invoked by the java compiler. Else, the user implemented or overridden toString() method is called.

Why is toString useful?

Edit: As for why it's rooted at the Object class, it's simply because ToString() is a valid operation for anything. Additionally, strings can be a good way of marshaling between data types or data consumers, because it's (practically) guaranteed to be parsable and doesn't require extra encoding or care.


It really depends on what you want to do with the returned value:

  • If you need to get the exact name used to declare the enum constant, you should use name() as toString may have been overriden
  • If you want to print the enum constant in a user friendly way, you should use toString which may have been overriden (or not!).

When I feel that it might be confusing, I provide a more specific getXXX method, for example:

public enum Fields {
    LAST_NAME("Last Name"), FIRST_NAME("First Name");

    private final String fieldDescription;

    private Fields(String value) {
        fieldDescription = value;
    }

    public String getFieldDescription() {
        return fieldDescription;
    }
}

Use name() when you want to make a comparison or use the hardcoded value for some internal use in your code.

Use toString() when you want to present information to a user (including a developper looking at a log). Never rely in your code on toString() giving a specific value. Never test it against a specific string. If your code breaks when someone correctly changes the toString() return, then it was already broken.

From the javadoc (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.


name() is a "built-in" method of enum. It is final and you cannot change its implementation. It returns the name of enum constant as it is written, e.g. in upper case, without spaces etc.

Compare MOBILE_PHONE_NUMBER and Mobile phone number. Which version is more readable? I believe the second one. This is the difference: name() always returns MOBILE_PHONE_NUMBER, toString() may be overriden to return Mobile phone number.


While most people blindly follow the advice of the javadoc, there are very specific situations where you want to actually avoid toString(). For example, I'm using enums in my Java code, but they need to be serialized to a database, and back again. If I used toString() then I would technically be subject to getting the overridden behavior as others have pointed out.

Additionally one can also de-serialize from the database, for example, this should always work in Java:

MyEnum taco = MyEnum.valueOf(MyEnum.TACO.name());

Whereas this is not guaranteed:

MyEnum taco = MyEnum.valueOf(MyEnum.TACO.toString());

By the way, I find it very odd for the Javadoc to explicitly say "most programmers should". I find very little use-case in the toString of an enum, if people are using that for a "friendly name" that's clearly a poor use-case as they should be using something more compatible with i18n, which would, in most cases, use the name() method.


A practical example when name() and toString() make sense to be different is a pattern where single-valued enum is used to define a singleton. It looks surprisingly at first but makes a lot of sense:

enum SingletonComponent {
    INSTANCE(/*..configuration...*/);

    /* ...behavior... */

    @Override
    String toString() {
      return "SingletonComponent"; // better than default "INSTANCE"
    }
}

In such case:

SingletonComponent myComponent = SingletonComponent.INSTANCE;
assertThat(myComponent.name()).isEqualTo("INSTANCE"); // blah
assertThat(myComponent.toString()).isEqualTo("SingletonComponent"); // better