我们有一个RESTAPI,客户机可以在其中提供表示java枚举中服务器上定义的值的参数。
所以我们可以提供一个描述性错误,我们添加了 lookup
方法对每个枚举执行。看起来我们只是在复制代码(糟糕)。有更好的做法吗?
public enum MyEnum {
A, B, C, D;
public static MyEnum lookup(String id) {
try {
return MyEnum.valueOf(id);
} catch (IllegalArgumentException e) {
throw new RuntimeException("Invalid value for my enum blah blah: " + id);
}
}
}
更新:由提供的默认错误消息 valueOf(..)
会是 No enum const class a.b.c.MyEnum.BadValue
. 我想从api中提供一个更具描述性的错误。
10条答案
按热度按时间lymgl2op1#
您可以使用静态查找Map来避免异常并返回null,然后根据需要抛出:
wpcxdonn2#
也许您可以实现通用的静态
lookup
方法。像这样
那你可以
或显式调用实用程序类查找方法。
yruzcnhs3#
看起来你在这里练习得不好,但不是在你想的地方。
抓住一个
IllegalArgumentException
改头换面RuntimeException
用更清晰的信息可能看起来是个好主意,但事实并非如此。因为这意味着您关心异常中的消息。如果您关心异常中的消息,那么这意味着您的用户以某种方式看到了您的异常。这很糟糕。
如果要向用户提供显式错误消息,则应在分析用户输入时检查枚举值的有效性,如果用户输入不正确,应在响应中发送相应的错误消息。
比如:
e1xvtsh34#
当涉及rest/json等时,我们所有的枚举都是这样做的。它的优点是错误是人类可读的,并且还提供了可接受的值列表。我们正在使用一个自定义方法myenum.fromstring而不是myenum.valueof,希望能有所帮助。
例如,如果你打电话
您将收到带有以下消息的illegalargumentexception:
“x”没有相应的值。接受值:[a、b、c、d]
您可以将illegalargumentexception更改为自定义。
atmip9wb5#
Guava也提供了这样的功能,它将返回
Optional
如果找不到枚举。xe55xuns6#
如果希望查找不区分大小写,可以通过值进行循环,使其更友好:
bvuwiixz7#
为什么我们要写5行代码?
dkqlctbz8#
illegalargumentexception中的错误消息已经具有足够的描述性。
您的方法对一个特定的异常生成一个通用异常,并简单地重写相同的消息。开发人员更喜欢特定的异常类型,并且可以适当地处理该情况,而不是试图处理runtimeexception。
如果目的是使消息更加用户友好,那么对枚举值的引用与它们无关。让ui代码决定应该向用户显示什么,ui开发人员最好使用illegalargumentexception。
hyrbngr79#
更新:正如绿海龟正确评论的那样,以下是错误的
我只会写信
这可能比捕获运行时异常的性能要差,但会使代码更干净。捕捉这样的异常总是一个坏主意,因为它容易被误诊。当检索比较值本身导致illegalargumentexception时会发生什么情况?然后将其视为枚举数的不匹配值。
ecfdbz9o10#
apache commons lang 3包含类enumutils。如果您在项目中没有使用ApacheCommons,那么您就错了。你在重新发明轮子!
我们可以毫无例外地使用十几种很酷的方法。例如:
获取类的枚举,如果找不到,则返回null。
此方法与enum.valueof的不同之处在于,它不会为无效的enum名称引发异常,并对名称执行不区分大小写的匹配。