【问题标题】:Exception handling best practices revised修改了异常处理最佳实践
【发布时间】:2011-03-12 00:44:25
【问题描述】:

我有一段代码在其中捕获所有异常并在最后抛出一个通用异常。像这样的:

try {
  // do something here
} catch (Whatever e) {
  throw new MyException(e.getMessage());
}

这种让我的函数定义看起来很干净,即“myFunc throws MyException”,但同时我失去了导致问题的语义。另一方面,如果我只是抛出所有异常,那将使函数体更干净,但函数的定义将包含 1-5 个抛出语句。

我的问题是:什么更好?...我应该捕获所有异常,保持函数定义干净,还是应该抛出所有东西保持函数体干净?

注意:第二种方法也会使我的函数的异常处理代码更加困难......

【问题讨论】:

标签: java exception exception-handling


【解决方案1】:

这通常是一个判断电话。您的函数应该公开与其所在层相关的异常。这通常意味着传递由您调用的事物引发的异常,有时不会。

例如,如果您有一个 getAThingy 函数,并且您的应用程序可以配置为使相关事物可以来自数据库或文件,则 getAThingy 可能不适合在其中引发 SqlException数据库案例,因为调用它的代码必须处理是否为文件或数据库配置。 (它会变成一个泄露的抽象。)所以这将是一个例子,说明你什么时候应该捕捉并抛出更合适的东西。

相比之下,如果您接受某种不应该是null 的标识符并且有人传入null,那么在不包装的情况下愉快地传递NullPointerException 似乎是完全合适的。

【讨论】:

  • 我完全同意这个答案。理解这些抽象概念并能在给定产品和代码库中想象它的人就是我对优秀程序员的定义。
【解决方案2】:

一个函数抛出 10 种不同类型的异常并没有错,只要每个异常在上下文中都有意义。

如果您只是想检测出问题,但您不需要确切知道是什么,您可以坚持您的方法(即只抛出一个异常)。

另一方面,如果你需要对不同的问题做出反应,你应该保留原来的异常。

没有“更好”的方法,这取决于上下文和您需要在上层拥有的信息。而且您不必担心保持主体或函数原型“干净”,这两种解决方案都是“干净”的。唯一重要的决策因素是信息需求。

【讨论】:

    【解决方案3】:

    为什么选择其中一个?

    try { /* doing useful work */ }
    catch (Whatever t) { throw new MyException(t); }
    

    其中MyException 有一个以Throwable 作为参数的构造函数。

    总的来说,我同意 Krtek 和 T.J.克劳德说过;抛出在您正在使用的抽象级别上有意义的异常,无论这意味着您列出一种还是十种异常。

    【讨论】:

      【解决方案4】:

      我听到的关于异常的建议是在尽可能靠近它们被抛出的地方处理它们。因此,例如,如果您可以从异常中恢复,请在引发异常的方法中执行此操作,并且根本不传播异常。如果您无法从异常中恢复,但可以编写一层或几层代码,请考虑传播它。还可以考虑返回一个简单地指示调用代码需要修复的值。

      如果您的异常无法从调用层次结构中某个适当位置的所有代码中恢复,则需要将其转换为用户友好的错误消息,最好是提醒用户修复异常并重新运行任务的方法甚至在发生错误的地方重新启动任务。

      最后,每当您包装异常时,并且有时您可能想要包装异常,请将整个异常包装为源,这样您就有很好的嵌套异常。

      【讨论】:

        【解决方案5】:

        如果您查看异常类的 Javadoc,您会发现它可以采用 Throwable。这实际上取决于您在做什么,但我通常选择通过执行以下操作来保留堆栈跟踪:

        catch(SomeException ex) {
            throw new ClearerException("This is what specifically went wrong", ex);
        }
        

        这样您就可以从可以输入的好消息中受益,但是如果您想深入研究并找到原因,堆栈跟踪也在那里。

        【讨论】:

          猜你喜欢
          • 2018-01-03
          • 1970-01-01
          • 2017-05-11
          • 2013-05-09
          • 2011-11-10
          • 1970-01-01
          • 2013-04-22
          相关资源
          最近更新 更多