Java - 枚举类型 valueOf 方法的“重写”命名约定

11

假设你有以下的枚举类型

public enum Color {
    RED("R"), GREEN("G"), BLUE("B");
    private String shortName;

    private Color(String shortName) {
        this.shortName = shortName;
    }

    public static Color getColorByName(String shortName) {
        for (Color color : Color.values()) {
            if (color.shortName.equals(shortName)) {
                return color;
            }
        }
        throw new IllegalArgumentException("Illegal color name: " + shortName);
    }
}

由于枚举是一种特殊情况,您无法仅覆盖valueOf函数,那么规避此问题并实现valueOf(String name)的命名约定是什么?

getColorByName(String name)
getValueOf(String name)
permissiveValueOf(String name)
customValueOf(String name)
forName(String name)
getEnum(String name)
getColor(String name)

后续编辑: 我看到Bloch在《Effective Java第二版》中提出了类似于getInstance()的东西(第1章,第1条)。 只是为了增加另一个选项。


5
覆盖方法保留名称。 - Eel Lee
即使重载保持相同的名称,但签名会有所不同。这听起来就像我们在谈论完全不同的名称... - Jon Skeet
5
各位...我们在谈论枚举。你不能重写valueOf()和values()方法。我会更改标题来强调这一点。但请撤回你们的反对票并给我一个答案。 - Alin Stoian
2
让我看看我是否理解正确:您正在询问如何命名一个方法,我们现在称其为“foo”,该方法将获取一个字符串(“R”、“G”或“B”),并返回正确的Color.RED / Color.Blue / Color.Green? - Elad Tabak
正确的,Elad。一个工厂方法将会返回确切的那个。我不介意“foo”成为惯例,但我怀疑这一点。 - Alin Stoian
显示剩余3条评论
3个回答

19

您说得没错,您不能覆盖Enum#valueOf(),因为它是Enum类的静态方法。

我不认为有命名约定。正如您已经指出的那样,Java 中有一些例子:

我不会使用getEnum,因为您不是在获取Enum本身,而是一个值。 在这里使用forName()不合适,因为R不是红色的名称

我更倾向于:

  • 使用fromString(),因为它是toString()的反义词;
  • 对于与Java标准库的一致性,使用getColor()

问题在于我无法在Java规范中找到枚举类型的任何示例。Color和Class是类而不是枚举类型。因此,您可以添加一个valueOf方法,但不能使用switch(color)。 - Alin Stoian
"fromBlah" 对我来说很有意义。例如,看看 Response.Status.fromStatusCode - jtoberon
没有标准,也不是很常见,因此你可能不会找到任何强烈的约定。除非你想开始使用cglib(!),fromString可能是最好的选择。当然,当别人读到它时,他们不会感到困惑。 - matt helliwell
为什么不使用 colorOf(String colorName) - Jan

2

请考虑以下内容!

Color fromName(String name);
Color fromShortName(String shortName);
Color fromCode(String code);

1
我会使用这对:
Color fromValue(String value)
String toValue()

这是我在枚举中发现最适合的东西。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接