Best practice to look up Java Enum

前端 未结 10 847
甜味超标
甜味超标 2021-02-01 13:17

We have a REST API where clients can supply parameters representing values defined on the server in Java Enums.

So we can provide a descriptive error, we add this

相关标签:
10条回答
  • 2021-02-01 13:49

    Apache Commons Lang 3 contais the class EnumUtils. If you aren't using Apache Commons in your projects, you're doing it wrong. You are reinventing the wheel!

    There's a dozen of cool methods that we could use without throws an Exception. For example:

    Gets the enum for the class, returning null if not found.

    This method differs from Enum.valueOf in that it does not throw an exceptionfor an invalid enum name and performs case insensitive matching of the name.

    EnumUtils.getEnumIgnoreCase(SeasonEnum.class, season);
    
    0 讨论(0)
  • 2021-02-01 13:51

    The error message in IllegalArgumentException is already descriptive enough.

    Your method makes a generic exception out of a specific one with the same message simply reworded. A developer would prefer the specific exception type and can handle the case appropriately instead of trying to handle RuntimeException.

    If the intent is to make the message more user friendly, then references to values of enums is irrelevant to them anyway. Let the UI code determine what should be displayed to the user, and the UI developer would be better off with the IllegalArgumentException.

    0 讨论(0)
  • 2021-02-01 13:52

    If you want the lookup to be case insensitive you can loop through the values making it a little more friendly:

     public enum MyEnum {
       A, B, C, D;
    
          public static MyEnum lookup(String id) {
            boolean found = false;
            for(MyEnum enum: values()){
               if(enum.toString().equalsIgnoreCase(id)) found = true;
            }  
            if(!found) throw new RuntimeException("Invalid value for my enum: " +id);
           }
    }
    
    0 讨论(0)
  • 2021-02-01 13:57

    We do all our enums like this when it comes to Rest/Json etc. It has the advantage that the error is human readable and also gives you the accepted value list. We are using a custom method MyEnum.fromString instead of MyEnum.valueOf, hope it helps.

    public enum MyEnum {
    
        A, B, C, D;
    
        private static final Map<String, MyEnum> NAME_MAP = Stream.of(values())
                .collect(Collectors.toMap(MyEnum::toString, Function.identity()));
    
        public static MyEnum fromString(final String name) {
            MyEnum myEnum = NAME_MAP.get(name);
            if (null == myEnum) {
                throw new IllegalArgumentException(String.format("'%s' has no corresponding value. Accepted values: %s", name, Arrays.asList(values())));
            }
            return myEnum;
        }
    }
    

    so for example if you call

    MyEnum value = MyEnum.fromString("X");
    

    you'll get an IllegalArgumentException with the following message:

    'X' has no corresponding value. Accepted values: [A, B, C, D]

    you can change the IllegalArgumentException to a custom one.

    0 讨论(0)
提交回复
热议问题