捕获单独的异常或使用instanceof - Java 6

时间:2013-03-21 08:47:11

标签: java exception-handling instanceof

假设这段代码在20个地方并且始终相同

try {
    // do something
} catch (FirstException e) {
    // log it
} catch (SecondException e) {
    // log it
}

使用这样的东西会不会更好或instanceof不是很好的解决方案?

try {
    // do something
} catch(Exception e) {
    logException(e);
}

void logException(Exception e) {
    if (e instanceof FirstException) {
        // log it
    } else if (e instanceof SecondException) {
        // log it differently
    } else {
        // do something with other exception 
    }
}

我唯一真正讨厌这个解决方案的是捕捉Exception,这绝不是最好的方式......有没有更好的方法?

4 个答案:

答案 0 :(得分:9)

  1. 在Java 7中,使用catch (FirstException1 | SecondException | ...)
  2. catch (Exception e)可能没有任何问题 - 您确实要记录所有例外情况,不是吗?我实际上会建议catch (Throwable t),因为OutOfMemoryErrorStackOverflowError也想要记录。
  3. 多年来记录异常的经验建议是以相同的方式记录它们。异常消息足以作为人类可读的文本,开发人员真正需要调试的是堆栈跟踪。

    小心一件事:永远不要过早捕获异常:在整个应用程序的单个位置捕获它们,所谓的异常障碍 -it位于您输入的级别退出工作单位。

    如果检查过的异常在较低级别给您带来麻烦,请将它们包装到RuntimeException

    try {
      ...
    } 
    catch (RuntimeException e) {throw e;} 
    catch (Exception e) {throw new RuntimeException(e);}
    

    如果您事先确切知道存在对您的应用程序具有业务级别含义的异常,并且中止当前的工作单元,但重定向其流量,是否适合在较低级别捕获该异常。实际上,与应用程序代码抛出的所有可能异常的总和相比,这种异常很少见。

答案 1 :(得分:1)

第一种方法肯定更好。通常,捕获Exception是一种不好的做法,因为在这种情况下,您也会捕获RuntimeException

答案 2 :(得分:1)

如果您只需要记录例外,那么前者是干净而且很好的解决方案。

其他第一种方法更好。

答案 3 :(得分:1)

在“重构为模式”一书中,常见的重构之一是“用多态性替换instanceof” - 换句话说,无论何时使用instanceof,都要考虑多态性实际上是否更好。 。

话虽如此,对于这个特殊的问题,Spring的理念是用运行时异常替换已检查的异常(请原谅双关语)。

这个想法是被检查的异常可能被过度使用 - 是可以从中恢复的例外吗?如果是的话,好的。 。 。如果没有,就让它传播到链条上。您可以通过以下方式执行此操作:

  • 重新投掷它。 。 。 (但还是更好)
  • 将其包装在RuntimeException

创建日志记录方面:

另一件需要考虑的事情是,如果你确实需要在它们发生的那一点上记录这些异常,而不是让它们向上传播, 它们会发生在20个不同的地方,他们是一个贯穿各领域的关注点。 。 。您可以使用常规方法重新抛出异常,然后编写一个方面来捕获并记录它们。 。 。 。再次使用Spring使这很容易。