两种方法之间的区别?

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

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐