4

I have a list of accounts types defined as enums in the web services implementation. However, when consumer call web service it passes a String that needs to be converted to enum.

What is a good way to validate that given String will be successfully converted to enum?

I was using the following approach, but this is probably an abuse of exceptions (according to Effective Java, item 57).

AccountType accountType = null;
try{
    accountType = AccountType.valueOf(accountTypeString);
}catch(IllegalArgumentException e){
    // report error
}

if (accountType != null){
    // do stuff
}else{
    // exit
}
Dima
  • 1,788
  • 2
  • 22
  • 30
  • 1
    See this thread, it has multiple solutions for this http://stackoverflow.com/questions/604424/java-convert-string-to-enum – Istvan Devai Jun 22 '12 at 19:53
  • How is this "probably an abuse of exceptions (according to Effective Java, item 57)" when data does not conform to normal expectations? You have exceptional data (in a bad way) if `IllegalArgumentException` is thrown because the conversion should normally succeed. Therefore this is the proper use of an exception. – D.B. Jun 30 '18 at 23:11

4 Answers4

2

You could go over the enum values and check if the name of each literal is equal to your string something like

for (Test test : Test.values()) {
    if (str.equals(test.name())) {
        return true;
    }
}
return false;

The enum is:

public enum Test {
    A,
    B,
}

Also you could return the enum constant or null, since enums are usually small it won't be a performance issue.

  • this is actually won't work, so on first iteration if str doesn't happen to be equal to the Enum type you will return false, even thought it might be still present in the array – Dima Jun 28 '12 at 17:10
  • If you take a deeper look, the "return false" statement will only happen after all the values on the array are checked, this is, when the for statement finishes. – Juan Alberto López Cavallotti Jun 28 '13 at 19:25
2

I personally used the EnumUtils from the Apache Commons library.

That library contains many useful util classes (e.g for Strings as well) and is a must have in any Java project and quite light (300ko).

Here is a sample code I use:

TypeEnum strTypeEnum = null;

// test if String str is compatible with the enum 
if( EnumUtils.isValidEnum(TypeEnum.class, str) ){
    strTypeEnum = TypeEnum.valueOf(str);
}
рüффп
  • 5,172
  • 34
  • 67
  • 113
1

You can catch IllegalArgumentException, that will be thrown when a bad value is given.

Rocky Pulley
  • 22,531
  • 20
  • 68
  • 106
  • I modified code to include IllegalArgumentException.. it is still and exceptions though – Dima Jun 22 '12 at 19:54
  • Yes, it is using exceptions how they should be used, not as a big catch all. I haven't see "item 57" you are referring to but I'm assuming that they are saying you should only thrown an exception when there is a real error, in this case it is an error and you couldn't avoid it anyway because the Java implementation is throwing that error. – Rocky Pulley Jun 22 '12 at 19:56
0

Use Optional data type from Guava.

Have your method AccountType.valueOf return value of type Optional<AccountType>. Then the use-site code would become:

Optional<AccountType> accountType = AccountType.valueOf(accountTypeString));
if (accountType.isPresent()) {
  AccountType a = accountType.get();
  // do stuff
} else {
  // exit
}
missingfaktor
  • 90,905
  • 62
  • 285
  • 365