I have Grade
enum and there is a static method to convert a string value to the particular enum value.
public enum Grade {
None("N"),
NotAccepted("-"),
Accepted("+"),
Uncertain("?");
private final String gradeSymbol;
Grade(String gradeSymbol) {
this.gradeSymbol = gradeSymbol;
}
public String getGradeSymbol() {
return gradeSymbol;
}
public static Grade fromGradeSymbol(final String gradeSymbol) {
switch (gradeSymbol) {
case "N":
return None;
case "-":
return NotAccepted;
case "+":
return Accepted;
case "?":
return Uncertain;
default:
throw new IllegalArgumentException("Unexpected grade symbol: " + gradeSymbol);
}
}
@Override
public String toString() {
return this.gradeSymbol;
}
}
My question is, what is better way to handle unexpected grade symbol in the static fromGradeSymbol()
method.
Another option I consider is the approach using Optional
and returning Optional.empty()
instead of throwing IllegalArgumentException
.
Like this:
public static Optional<Grade> fromGradeSymbol(final String gradeSymbol) {
switch (gradeSymbol) {
case "N":
return Optional.of(None);
case "-":
return Optional.of(NotAccepted);
case "+":
return Optional.of(Accepted);
case "?":
return Optional.of(Uncertain);
default:
return Optional.empty();
}
}
My thoughts:
Throwing exception looks more logical, because it is being thrown in not expected case, when wrong value has been passed. But throwing exception makes it necessary to catch this exception anywhere where I convert string to the enum.
Use of Optional
does not involve exceptions and makes cleaner code, without try-catch construct. But it somehow hides
the unexpected input.
Sure, I can assume that every time when Optional does not contain a value we have an unexpected input. But it feels like code smell.
What do you think?
Grade.values()
. If you need to callfromGradeSymbol
frequently, then you should build a staticMap<String, Grade>
and use that. \$\endgroup\$Optional
and throwingIllegalArgumentException
? Do you share my thoughts or have different opinion ? \$\endgroup\$