如果你在方法name()
中查看enum api,它会说:
返回此枚举常量的名称,与其枚举声明中声明的完全相同。 大多数程序员应优先使用toString方法, 因为toString方法可能返回一个更加用户友好的名称。 此方法主要用于特殊情况,其中正确性取决于获取确切名称,不会因发行版本而异。
为什么最好使用toString()
?我的意思是当name()已经是final时,可以覆盖toString。因此,如果您使用toString并且有人覆盖它以返回硬编码值,则整个应用程序都会关闭...另外,如果您查看源代码,则toString()方法将返回完全正确的名称。这是一回事。
答案 0 :(得分:188)
这实际上取决于你想要对返回值做什么:
name()
,因为toString
可能已被覆盖toString
(或不!)。当我觉得它可能令人困惑时,我会提供更具体的getXXX
方法,例如:
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;
}
}
答案 1 :(得分:53)
如果您想进行比较,请使用name()
或在代码中使用硬编码值进行内部使用。
如果要向用户显示信息(包括查看日志的开发人员),请使用toString()
。永远不要依赖toString()
给出特定值的代码。切勿针对特定字符串进行测试。如果在有人正确更改toString()
返回时您的代码中断,那么它已经被破坏了。
来自javadoc(强调我的):
返回对象的字符串表示形式。一般来说, toString方法返回一个字符串“textually represent” this 宾语。结果应该是简洁但信息丰富的表示 一个人阅读很容易。 建议全部 子类重写此方法。
答案 2 :(得分:23)
name()
是enum
的“内置”方法。这是最终的,你不能改变它的实现。它在写入时返回枚举常量的名称,例如:大写,没有空格等。
比较MOBILE_PHONE_NUMBER
和Mobile phone number
。哪个版本更具可读性?我相信第二个。这是不同的:name()
始终返回MOBILE_PHONE_NUMBER
,toString()
可以覆盖以返回Mobile phone number
。
答案 3 :(得分:12)
虽然大多数人盲目地遵循javadoc的建议,但是在非常具体的情况下你想要实际避免使用toString()。例如,我在我的Java代码中使用枚举,但是需要将它们序列化到数据库,然后再返回。如果我使用toString()那么我在技术上会受到其他人指出的被覆盖的行为的影响。
此外,还可以从数据库中反序列化,例如,这应始终使用Java:
MyEnum taco = MyEnum.valueOf(MyEnum.TACO.name());
虽然无法保证:
MyEnum taco = MyEnum.valueOf(MyEnum.TACO.toString());
顺便说一句,我发现Javadoc明确地说'#34;大多数程序员应该"这是非常奇怪的。我发现枚举的toString中只有很少的用例,如果人们使用它作为一个友好的名字"这显然是一个糟糕的用例,因为他们应该使用与i18n更兼容的东西,在大多数情况下,它会使用name()方法。
答案 4 :(得分:4)
name()实际上是枚举的java代码中的文本名称。这意味着它仅限于实际出现在java代码中的字符串,但并非所有可能的字符串都可以在代码中表达。例如,您可能需要一个以数字开头的字符串。 name()将永远无法为您获取该字符串。
答案 5 :(得分:4)
当name()和toString()有意义不同时的一个实际例子是使用单值枚举来定义单例的模式。起初看起来令人惊讶,但很有意义:
enum SingletonComponent {
INSTANCE(/*..configuration...*/);
/* ...behavior... */
@Override
String toString() {
return "SingletonComponent"; // better than default "INSTANCE"
}
}
在这种情况下:
SingletonComponent myComponent = SingletonComponent.INSTANCE;
assertThat(myComponent.name()).isEqualTo("INSTANCE"); // blah
assertThat(myComponent.toString()).isEqualTo("SingletonComponent"); // better
答案 6 :(得分:-1)
您还可以使用类似下面的代码。我使用lombok来避免为吸气剂和构造剂编写一些样板代码。
@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;
}
}