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

捕获单独的异常或使用instanceof-java6,java,exception-handling,instanceof,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 l

假设这段代码位于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 
    }
}

这个解决方案唯一让我讨厌的是捕获
异常
,这绝对不是最好的方法。。。有更好的方法吗?

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

如果您只需记录异常,前者是一个干净而伟大的解决方案

否则第一种方法更好

  • 在Java7中,使用
    catch(FirstException1 | SecondException |…)
  • catch(异常e)
    可能没有问题-您确实想记录所有异常,是吗?事实上,我会建议
    catch(Throwable t)
    ,因为
    OutOfMemoryError
    s和
    stackoverflowererror
    s也需要记录
  • 多年记录异常的经验告诉我们,以同样的方式记录异常。异常消息作为人类可读的文本就足够了,开发人员调试真正需要的是堆栈跟踪

    请注意一件事:永远不要过早捕获异常:在整个应用程序的单个位置捕获异常,所谓的异常屏障是在您进入和退出工作单元的级别

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

    try {
      ...
    } 
    catch (RuntimeException e) {throw e;} 
    catch (Exception e) {throw new RuntimeException(e);}
    
    只有如果您事先准确地知道存在对应用程序具有业务级别意义的异常,并且不会中止当前工作单元,而是重定向其流,那么在较低级别捕获该异常是否合适。在实践中,这样的异常与应用程序代码中可能出现的所有异常相比是罕见的。

    < P>在“重构到模式”中,一个常见的重构是“用多态替换实例”——换句话说,每当使用实例时,就考虑多形现象是否会更好地工作… 话虽如此,对于这个特殊的问题,我想到了用运行时异常替换检查异常的Spring哲学(请原谅双关语)

    其思想是,检查过的异常可能被过度使用——异常是否可以从中恢复?如果是,好的。如果没有,就让它沿着链条向上传播。您可以通过以下方式完成此操作:

    • 你在扔它。(但更好)
    • 将其包装在RuntimeException中
    创建日志方面:


    另一个要考虑的是,如果确实需要记录这些异常,而不是让它们在链上传播,<强>和< /强>它们发生在20个不同的地方,那么它们是交叉的关注点…您可以让常规方法重新显示异常,然后编写一个方面来捕获并记录它们。再次使用Spring使这变得容易

    我会使用第一种方法,为所有捕获的异常调用logException。如果抛出
    FileNotFoundException
    ,会发生什么!!!仅当您打算对每个异常执行不同的处理时,单独捕获每个异常才有意义。在实际应用中,这种情况很少发生。可行的方法是,如果运行时错误是一个主要问题,则使用超类
    异常
    丢弃
    捕获它们,并正确记录它们,以便开发人员了解实际发生的位置和情况。捕获丢弃不就是最大的罪恶吗?因为我不想抓住所有的例外。。。只有在太早捕捉到它们的情况下,才可以捕捉到这两个异常——正如我在编辑后的答案中解释的那样。谢谢——我不知道在java 7中可以捕捉到异常a | b(最近主要在Obj-C中工作)。方便的提示。