【问题标题】:When to use multi-catch and when to use rethrow?什么时候使用multi-catch,什么时候使用rethrow?
【发布时间】:2017-09-13 01:45:34
【问题描述】:

我对这两个主题非常不确定。我知道我应该使用 multi-catch 来处理需要以相同方式处理的异常。但是我真的需要这样的东西是为了什么目的。

private void something(String name) throws IOException, RemoteException {
    try {
        ...
    } catch (Exception ex) {

        ... // do something

        throw ex;
    }
}

【问题讨论】:

  • 使用通用异常是一种不好的做法。见here
  • 这个问题是不是既不清楚又基于意见?

标签: java rethrow multi-catch


【解决方案1】:

如果您认为此方法在执行期间抛出的任何异常都应以相同的方式处理,并且您希望在将异常传播到客户端之前执行任务,则可以这样做

例如,假设您想在异常发生时进行特定处理,例如记录信息。所以你抓住它来做这个任务。
尽管如此,您认为捕获的异常是一个问题,并且记录它不是对异常的“真正”处理。所以,你让它通过重新抛出来传播。

【讨论】:

  • 好的,谢谢。但我可以再问一个问题吗?让我们假设一个 NullPointerException 被抛出并被捕获。这个异常是否也会被抛出给调用方法,因为在 throws-clause 中只提到了 IO- 和 RemoteException ?来自德国的问候
  • 不客气。非常有趣的问题。 NullPointerExceptionRuntimeException。这种异常不需要在方法声明中显式声明。您可以在不捕获它或将方法声明为抛出它的情况下将其扔掉。与检查异常的IOExceptionRemoteException 相反。这些最后派生自 Exception 而不是 RuntimeException
  • 这是真的……我没有考虑到这一点。如果抛出 IllegalArgumentException 会发生什么,例如因为我想将字符串存储在 int 变量中?尽管 throws 子句中没有提到它,但它是否会被抛出到调用方法?
  • 当然,它会被扔给调用方法,但由于它是RuntimeException,调用者可能决定不处理它。当你想确保异常被处理(抛出或捕获)时,你应该使用检查异常(... extends Exception)。如果合适,请不要犹豫,创建自己的。
  • 那是我的笨拙。 xD 我忘了它也是一个 RuntimeException 。我真正想问的是,如果在 try 块中发生已检查的异常并且交给 catch 块然后抛出到调用方法而不在 throws 子句中提及它会发生什么。长话短说,我终于测试了它,答案是(就像你之前提到的那样)如下:当我抛出一个检查的异常时,无论抛出子句中是否提到异常,调用方法都必须处理它自己。 xD 非常感谢!
【解决方案2】:

以下情况需要重新抛出

  1. 您希望在让异常离开方法之前对某些内容进行预处理。但是,如果您不关心异常的类型,也可以在 finally 块中进行预处理。
  2. 您正在尝试将已检查的异常转换为未检查的异常。在这种情况下,您将捕获所有异常为 catch(Exception ex) 并将它们重新抛出为 throw new RuntimeException(ex)
  3. 您希望抛出自定义异常而不是内置异常。因此,您将捕获所有异常,然后创建自己的异常对象,最好是未经检查的对象并抛出它。许多 API 都会这样做,例如 Spring 将不直观的 JDBC 异常转换为 Spring 自定义异常。
  4. 这有点像预处理。您想跟踪通过创建 ArrayList 或其他东西引发的所有异常,以便在具有多个步骤的程序结束时知道哪些步骤引发了异常。我已经看到在Talend 生成的Java 代码中使用了这个。

【讨论】:

    【解决方案3】:

    重投

    当你想通知调用者方法异常时,你捕获并重新抛出异常。

    说一些方法 callSomething() 正在调用你的方法 something()。如果某事物() 内部发生任何异常,它只会捕获异常,因此应用程序不会失败,并将其重新抛出到 callSomething() 方法。然后 callSomething() 将通知客户端内部错误。

    另一个例子是,在 MVC 模式中,客户端提交的请求由控制器基于请求映射的某种方法提供服务。 Controller会调用service,service会和dao的一些方法进行交互。如果 DAO 发生异常,DAO 将向服务重新抛出异常,服务将向控制器重新抛出,控制器将错误消息通知客户端。 这在 java 中称为 异常传播异常从一个方法传播到另一个方法,沿着调用堆栈向上传播,直到它被捕获

    多抓

    如果您想对多种类型的异常执行相同的操作,那么您可以使用 multi catch。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-04
      • 1970-01-01
      • 1970-01-01
      • 2022-11-10
      相关资源
      最近更新 更多