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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9662170/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-16 05:47:12  来源:igfitidea点击:

Override valueof() and toString() in Java enum

javaenumsoverridingtostringvalue-of

提问by WildBamaBoy

The values in my enumare words that need to have spaces in them, but enums can't have spaces in their values so it's all bunched up. I want to override toString()to add these spaces where I tell it to.

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

I also want the enum to provide the correct enum when I use valueOf()on the same string that I added the spaces to.

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

For example:

例如:

public enum RandomEnum
{
     StartHere,
     StopHere
}

Call toString()on RandomEnumwhose value is StartHerereturns string "Start Here". Call valueof()on that same string ("Start Here") returns enum value StartHere.

电话toString()上的RandomEnum,其值是StartHere返回字符串"Start Here"。调用valueof()同一个字符串 ( "Start Here") 返回枚举值StartHere

How can I do this?

我怎样才能做到这一点?

采纳答案by Jugal Shah

You can try out this code. Since you cannot override valueOfmethod you have to define a custom method (getEnumin the sample code below) which returns the value that you need and change your client to use this method instead.

你可以试试这个代码。由于您无法覆盖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();
    }
}

回答by Java42

I don't think your going to get valueOf("Start Here") to work. But as far as spaces...try the following...

我认为您不会让 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

回答by exception

The following is a nice generic alternative to valueOf()

以下是 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);
}

回答by pedorro

You can use a static Map in your enum that maps Strings to enum constants. Use it in a 'getEnum' static method. This skips the need to iterate through the enums each time you want to get one from its String value.

您可以在枚举中使用静态 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;
    }
}

Just make sure the static initialization of the map occurs below the declaration of the enum constants.

只需确保映射的静态初始化发生在枚举常量的声明下方。

BTW - that 'ImmutableMap' type is from the Google guava API, and I definitely recommend it in cases like this.

顺便说一句 - 'ImmutableMap' 类型来自 Google guava API,在这种情况下我绝对推荐它。



EDIT - Per the comments:

编辑 - 根据评论:

  1. This solution assumes that each assigned string value is unique and non-null. Given that the creator of the enum can control this, and that the string corresponds to the unique & non-null enum value, this seems like a safe restriction.
  2. I added the 'toSTring()' method as asked for in the question
  1. 此解决方案假定每个分配的字符串值都是唯一且非空的。鉴于枚举的创建者可以控制这一点,并且字符串对应于唯一且非空的枚举值,这似乎是一个安全的限制。
  2. 我添加了问题中要求的“toSTring()”方法

回答by Bat

Try this, but i don't sure that will work every where :)

试试这个,但我不确定它是否适用于所有地方:)

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) {}
    }
}

回答by corlaez

How about a Java 8 implementation? (null can be replaced by your default Enum)

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

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);
}

Or you could use:

或者你可以使用:

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

回答by Andrey Lebedenko

You still have an option to implement in your enum this:

您仍然可以选择在您的枚举中实现:

public static <T extends Enum<T>> T valueOf(Class<T> enumType, String name){...}