在Java枚举中覆盖valueof()和toString()

时间:2012-03-12 05:32:53

标签: java enums override tostring value-of

我的enum中的值是需要在其中包含空格的单词,但枚举中的值不能包含空格,因此它们全部聚集在一起。我想覆盖toString()以在我告诉它的地方添加这些空格。

当我在添加空格的相同字符串上使用valueOf()时,我也希望枚举能够提供正确的枚举。

例如:

public enum RandomEnum
{
     StartHere,
     StopHere
}

toString()上呼叫RandomEnum,其值为StartHere,返回字符串"Start Here"。在同一个字符串(valueof())上调用"Start Here"会返回枚举值StartHere

我该怎么做?

6 个答案:

答案 0 :(得分:177)

您可以试用此代码。由于您无法覆盖valueOf方法,因此您必须在下面的示例代码中定义自定义方法(getEnum),该方法会返回您需要的值并更改您的客户端以使用此方法。

public enum RandomEnum {

    StartHere("Start Here"),
    StopHere("Stop Here");

    private String value;

    RandomEnum(String value) {
        this.value = value;
    }

    public String getValue() {
        return value;
    }

    @Override
    public String toString() {
        return this.getValue();
    }

    public static RandomEnum getEnum(String value) {
        for(RandomEnum v : values())
            if(v.getValue().equalsIgnoreCase(value)) return v;
        throw new IllegalArgumentException();
    }
}

答案 1 :(得分:22)

试试这个,但我不确定每个地方都会有效:)

public enum MyEnum {
    A("Start There"),
    B("Start Here");

    MyEnum(String name) {
        try {
            Field fieldName = getClass().getSuperclass().getDeclaredField("name");
            fieldName.setAccessible(true);
            fieldName.set(this, name);
            fieldName.setAccessible(false);
        } catch (Exception e) {}
    }
}

答案 2 :(得分:10)

您可以在枚举中使用静态Map,将字符串映射到枚举常量。在'getEnum'静态方法中使用它。这样就无需在每次想要从String值中获取枚举时迭代枚举。

public enum RandomEnum {

    StartHere("Start Here"),
    StopHere("Stop Here");

    private final String strVal;
    private RandomEnum(String strVal) {
        this.strVal = strVal;
    }

    public static RandomEnum getEnum(String strVal) {
        if(!strValMap.containsKey(strVal)) {
            throw new IllegalArgumentException("Unknown String Value: " + strVal);
        }
        return strValMap.get(strVal);
    }

    private static final Map<String, RandomEnum> strValMap;
    static {
        final Map<String, RandomEnum> tmpMap = Maps.newHashMap();
        for(final RandomEnum en : RandomEnum.values()) {
            tmpMap.put(en.strVal, en);
        }
        strValMap = ImmutableMap.copyOf(tmpMap);
    }

    @Override
    public String toString() {
        return strVal;
    }
}

确保地图的静态初始化发生在枚举常量的声明之下。

BTW - 'ImmutableMap'类型来自Google guava API,我肯定会在这种情况下推荐它。


编辑 - 根据评论:

  1. 此解决方案假定每个分配的字符串值都是唯一且非空。鉴于枚举的创建者可以控制它,并且该字符串对应于唯一的&amp;非空枚举值,这似乎是一个安全的限制。
  2. 我在问题
  3. 中添加了'toSTring()'方法

答案 3 :(得分:10)

Java 8实现怎么样? (null可以替换为您的默认枚举)

public static RandomEnum getEnum(String value) {
    List<RandomEnum> list = Arrays.asList(RandomEnum.values());
    return list.stream().filter(m -> m.value.equals(value)).findAny().orElse(null);
}

或者您可以使用:

...findAny().orElseThrow(NotFoundException::new);

答案 4 :(得分:2)

我不认为你会得到valueOf(“Start Here”)来工作。 但就空间而言......尝试以下......

static private enum RandomEnum {
    R("Start There"), 
    G("Start Here"); 
    String value;
    RandomEnum(String s) {
        value = s;
    }
}

System.out.println(RandomEnum.G.value);
System.out.println(RandomEnum.valueOf("G").value);

Start Here
Start Here

答案 5 :(得分:2)

以下是valueOf()

的一个很好的通用替代方法
public static RandomEnum getEnum(String value) {
  for (RandomEnum re : RandomEnum.values()) {
    if (re.description.compareTo(value) == 0) {
      return re;
    }
  }
  throw new IllegalArgumentException("Invalid RandomEnum value: " + value);
}