两种方法之间的区别?
Java枚举有两种方法来检索枚举常量的值: name()和.toString() 。 toString()方法调用name()方法,该方法返回枚举常量的字符串表示形式。 在清单1中,通过在Animal.DOG常量方法上调用name()和toString()返回的值是DOG 。
清单1:动物枚举
public enum Animal {
DOG
}
// Unit test
assertThat(DOG.toString()).isEqualTo(DOG.name());
因此,鉴于两种方法都返回相同的值,您可能会认为它们可以互换使用,并且在大多数情况下,这是正确的。 但是,这两种方法之间的区别很重要。
有什么不同?
name()方法是最终的,因此不能被覆盖,相反, toString()方法是打开的并且可以被覆盖。 实际上,鼓励重写toString()方法。 应该实现它并返回友好的枚举常量版本。 清单2显示了如何完成此操作。
清单2:覆盖toString()方法
public enum Animal {
DOG {
public String toString() {
return "Dog";
}
}
}
// Unit test
assertThat(DOG.toString()).isNotEqualTo(DOG.name());
在Animal.DOG枚举常量上调用toString()的输出为Dog 。 因此,现在name()方法和toString()方法不会返回相同的值。
Java文档怎么说
让我们更深入地研究一下Java文档,该文档建议:
大多数程序员应该优先于name()方法使用toString()方法,因为toString()方法可能返回更用户友好的名称。
这就提出了一个问题。 什么时候应该使用.name()方法?
根据Java文档:
name()方法主要设计用于特殊情况,在这些情况下正确性取决于获得确切的名称,而不同的发布版本之间并不会有所不同。
那么他们指的是什么特殊情况? valueOf()方法可能会给我们提示。 此方法采用String值,并尝试查找与之完全匹配的枚举。 看一下清单3中的代码。
清单3:valueOf()方法返回DOG
assertThat(DOG).isEqualTo(Animal.valueOf("DOG"));
传递给valueOf()方法的String值必须与枚举常量完全匹配,否则将引发IllegalArgumentException 。
源代码
本文的代码示例和单元测试存储在GitHub存储库ReadLearnCode / readlearncode_articles中 。
结论
当基于字符串值填充枚举字段时,这是一种非常有用的方法。 何时执行此操作的一个示例是在反序列化包含枚举常量的JSON文档时。 在这种情况下,应使用name()方法以保持往返等效性。
您不能保证toString()方法不会被覆盖,但是name()方法将始终返回枚举的字符串等效项。
进一步阅读
您可能对我的文章“策略模式的枚举实现”感兴趣。
翻译自: https://www.javacodegeeks.com/2017/09/enum-use-name-tostring-methods-correctly.html
所有评论(0)