【发布时间】:2017-09-18 13:43:13
【问题描述】:
这不是关于一般异常处理的问题,但它专门适用于某些框架的使用。几个典型起点的例子:
- GWT:
public void onFailure(Throwable caught)实现AsyncCallback接口。 - JAX-RS:
public Response toResponse(E throwable)实现ExceptionMapper<E extends Throwable>接口。
上述两种方法都接收Throwable 的实例。通常,我看到开发人员使用简单的“if/else if”块来区分处理逻辑:
// As specified by the AsyncCallback class of the GWT framework
public void onFailure(Throwable caught) {
if (caught instanceof AnException) {
// handle AnException
} else if (caught instanceof AnotherException) {
// handle AnotherException
} else if (caught instanceof YetAnotherException) {
// handle YetAnotherException
} else if (caught instanceof ...) {
// and so on...
}
}
由于许多原因我不喜欢“if/else if”块,我想出了以下“模式”,它将“if/else if”块转换为“try/catch”块,表现就好像它是一个“开关”块:
public void onFailure(Throwable caught) {
try {
throw caught;
} catch(AnException e1) {
// handle AnException
} catch(AnotherException e2) {
// handle AnotherException
} catch(YetAnotherException e3) {
// handle YetAnotherException
} catch(...) {
// and so on...
}
}
我的问题是:在性能、最佳实践、代码可读性、一般安全性或其他任何我没有考虑或注意到的方面 - 使用这种方法是否有任何缺点?
【问题讨论】:
-
另一种方法是将不同的逻辑放入异常类型本身(如果它们是您自己的),这样您就可以有一个子句。事实上,如果大多数异常是您自己的已检查异常,我会建议您这样做。很多 if/else/switch 行为最好是多态
-
@Novaterata 是的,这种情况是使用 JAX-RS 框架处理的,您可以在其中创建特定的
ExceptionMapper<E extends Throwable>实现来处理您自己的检查异常。但有时框架会强制您只处理Throwable(例如 GWT)。 -
我觉得它看起来不错。一个小缺点是如果您忘记了“包罗万象”子句并将错误从错误处理代码“发送回”框架。有朝一日可能会导致艰难的调试会话。
-
@jannis 目的不是流量控制,而是异常处理。如果我不使用提到的框架,我什至不会费心发布这样的问题。框架要求我按照自己的规则工作,所以我需要适应。我编辑了我的问题,添加了粗体字以指出我在寻找什么。