Override valueof() and toString() in Java enum

匿名 (未验证) 提交于 2019-12-03 09:05:37

问题:

The values in my enum are 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.

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

For example:

public enum RandomEnum {      StartHere,      StopHere } 

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

How can I do this?

回答1:

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

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


回答2:

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


回答3:

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

public static RandomEnum getEnum(String value) {     List 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); 


回答4:

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.

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 strValMap;     static {         final Map 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.


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


回答5:

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

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 


回答6:

The following is a nice generic alternative to 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); } 


回答7:

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

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


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!