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

在我的enum值是需要有空格的单词,但枚举不能在他们的价值空间,所以它都成了。 我想重写toString()来添加这些空间,我告诉它。

我也希望枚举提供正确的枚举,当我使用valueOf()在我添加空格相同的string。

例如:

 public enum RandomEnum { StartHere, StopHere } 

对值为StartHere调用toString()将返回string"Start Here" 。 在同一个string( "Start Here" )上StartHere ()将返回枚举值StartHere

我怎样才能做到这一点?

你可以试试这个代码。 由于您无法覆盖valueOf方法,因此您必须定义一个自定义方法( getEnum的示例代码中的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(); } } 

试试这个,但我不确定那会工作在每个地方:)

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

你可以在你的枚举中使用一个静态的Map来把Strings映射到枚举常量。 在“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; } } 

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

顺便说一句,那'ImmutableMap'types是从谷歌guava API,我绝对推荐它在这种情况下。


编辑 – 根据评论:

  1. 此解决scheme假定每个分配的string值都是唯一的且非空的。 鉴于枚举的创build者可以控制这个,并且该string对应于唯一的&非空枚举值,这似乎是一个安全的限制。
  2. 我在问题中添加了“toSTring()”方法

Java 8实现如何? (null可以被你的默认枚举replace)

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

我不认为你会得到valueOf(“从这里开始”)工作。 但是,至于空间…尝试以下…

 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 

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