什么时候使用 multi-catch 什么时候使用 rethrow?
When to use multi-catch and when to use rethrow?
我对这两个话题很不确定。我知道我应该对需要以相同方式处理的异常使用 multi-catch。但是为了什么目的我真的需要这样的东西。
private void something(String name) throws IOException, RemoteException {
try {
...
} catch (Exception ex) {
... // do something
throw ex;
}
}
如果你认为对于这个方法在执行过程中抛出的任何异常都应该以相同的方式处理,并且你希望在将异常传播到客户端之前执行一个任务,你就可以这样做
比如,假设你想在异常发生时做一个特定的处理,比如记录信息。所以你抓住它来完成这个任务。
尽管如此,您认为捕获的异常是一个问题并且记录它不是异常的 "real" 处理。因此,您可以通过重新抛出它来让它传播。
重新投掷
每当你想通知调用方方法异常时,你捕获并重新抛出异常。
假设某个方法 callSomething() 正在调用您的方法 something()。如果在 something() 中发生任何异常,它只会捕获异常,因此应用程序不会失败,并将其重新抛给 callSomething() 方法。然后 callSomething() 将通知客户端内部错误。
另一个例子是,在 MVC 模式中,客户端提交的请求由基于请求映射的控制器中的某种方法提供服务。 controller会调用service,service会和dao的一些方法进行交互。如果DAO中出现异常,DAO会重新抛出异常给service,service会重新抛给controller,controller会通知client错误信息。
这在 java 中称为 异常传播。 异常从一个方法传播到另一个方法,在调用堆栈中向上传播,直到被捕获。
多抓
如果要对多种类型的异常执行相同的操作,则使用 multi catch。
以下情况需要重新抛出
- 您想在让异常离开方法之前预处理一些东西。但是,如果您不关心异常的类型,那么预处理也可以在
finally
块中完成。
- 您正在尝试将已检查的异常转换为未检查的异常。在那种情况下,您将捕获所有异常
catch(Exception ex)
并将它们重新抛出为 throw new RuntimeException(ex)
.
- 您希望抛出自定义异常而不是内置异常。因此,您将捕获所有异常,然后创建您自己的异常对象(最好是未检查的异常对象)并抛出它。许多 API 都这样做,例如 Spring 将不直观的
JDBC
异常转换为 Spring 自定义异常。
- 这有点像预处理。您想跟踪通过创建 ArrayList 或其他东西抛出的所有异常,以便在包含多个步骤的程序结束时您知道哪些步骤抛出异常。我已经看到这个被用在
Talend
生成的 Java 代码中。
我对这两个话题很不确定。我知道我应该对需要以相同方式处理的异常使用 multi-catch。但是为了什么目的我真的需要这样的东西。
private void something(String name) throws IOException, RemoteException {
try {
...
} catch (Exception ex) {
... // do something
throw ex;
}
}
如果你认为对于这个方法在执行过程中抛出的任何异常都应该以相同的方式处理,并且你希望在将异常传播到客户端之前执行一个任务,你就可以这样做
比如,假设你想在异常发生时做一个特定的处理,比如记录信息。所以你抓住它来完成这个任务。
尽管如此,您认为捕获的异常是一个问题并且记录它不是异常的 "real" 处理。因此,您可以通过重新抛出它来让它传播。
重新投掷
每当你想通知调用方方法异常时,你捕获并重新抛出异常。
假设某个方法 callSomething() 正在调用您的方法 something()。如果在 something() 中发生任何异常,它只会捕获异常,因此应用程序不会失败,并将其重新抛给 callSomething() 方法。然后 callSomething() 将通知客户端内部错误。
另一个例子是,在 MVC 模式中,客户端提交的请求由基于请求映射的控制器中的某种方法提供服务。 controller会调用service,service会和dao的一些方法进行交互。如果DAO中出现异常,DAO会重新抛出异常给service,service会重新抛给controller,controller会通知client错误信息。 这在 java 中称为 异常传播。 异常从一个方法传播到另一个方法,在调用堆栈中向上传播,直到被捕获。
多抓
如果要对多种类型的异常执行相同的操作,则使用 multi catch。
以下情况需要重新抛出
- 您想在让异常离开方法之前预处理一些东西。但是,如果您不关心异常的类型,那么预处理也可以在
finally
块中完成。 - 您正在尝试将已检查的异常转换为未检查的异常。在那种情况下,您将捕获所有异常
catch(Exception ex)
并将它们重新抛出为throw new RuntimeException(ex)
. - 您希望抛出自定义异常而不是内置异常。因此,您将捕获所有异常,然后创建您自己的异常对象(最好是未检查的异常对象)并抛出它。许多 API 都这样做,例如 Spring 将不直观的
JDBC
异常转换为 Spring 自定义异常。 - 这有点像预处理。您想跟踪通过创建 ArrayList 或其他东西抛出的所有异常,以便在包含多个步骤的程序结束时您知道哪些步骤抛出异常。我已经看到这个被用在
Talend
生成的 Java 代码中。