Java enum - why use toString instead of name

后端 未结 7 1984
清酒与你
清酒与你 2020-11-28 22:18

If you look in the enum api at the method name() it says that:

Returns the name of this enum constant, exactly as declared in its enum declaration.

相关标签:
7条回答
  • 2020-11-28 22:34

    name() is literally the textual name in the java code of the enum. That means it is limited to strings that can actually appear in your java code, but not all desirable strings are expressible in code. For example, you may need a string that begins with a number. name() will never be able to obtain that string for you.

    0 讨论(0)
  • 2020-11-28 22:42

    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;
        }
    }
    
    0 讨论(0)
  • 2020-11-28 22:45

    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
    
    0 讨论(0)
  • 2020-11-28 22:55

    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.

    0 讨论(0)
  • 2020-11-28 22:56

    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.

    0 讨论(0)
  • 2020-11-28 22:56

    You can also use something like the code below. I used lombok to avoid writing some of the boilerplate codes for getters and constructor.

    @AllArgsConstructor
    @Getter
    public enum RetroDeviceStatus {
        DELIVERED(0,"Delivered"),
        ACCEPTED(1, "Accepted"),
        REJECTED(2, "Rejected"),
        REPAIRED(3, "Repaired");
    
        private final Integer value;
        private final String stringValue;
    
        @Override
        public String toString() {
            return this.stringValue;
        }
    }
    
    0 讨论(0)
提交回复
热议问题