【问题标题】:Handling several exceptions in Java在 Java 中处理几个异常
【发布时间】:2012-07-16 18:20:58
【问题描述】:

考虑以下 Java 代码:

try{

    // do something
    // this piece of code throws several checked exceptions.

} catch (IllegalArgumentException e) {
    handleException(e);
} catch (IllegalAccessException e) {
    handleException(e);
} catch (InvocationTargetException e) {
    handleException(e);
} catch (InstantiationException e) {
    handleException(e);
} catch (NoSuchMethodException e) {
    handleException(e);
} catch (IOException e) {
    handleException(e);
} catch (NoSuchFieldException e) {
    handleException(e);
}

try 块中的代码抛出了几个检查异常。我要做的就是在发生异常时记录一条消息(使用一些自定义消息字符串)。 IE。对于所有异常,我的异常处理逻辑是相同的。

我觉得上面的代码看起来不太好(更多的 LOC 和降低的可读性)。

有没有更好的方法来处理这种情况?

以下解决方案不是最佳实践,因此不推荐(按 Check 样式)。

try{
    // do something very bad
} catch (Exception e) {
    handleException(e);
} 

【问题讨论】:

  • 使用 Java 7 可以聚合异常。捕获Exception 本身并不错,平等地处理所有Exception 实例。
  • 您不应盲目遵循最佳实践。每个最佳实践都有反例。在这种情况下,如果您确定不会轻易更改异常处理,我认为使用单个通用 catch 是合理的。
  • 查看 marco 方法。你通过一个好的实践来解决问题......如果你只捕获异常,你会掩盖未检查的异常。这不是做最佳实践的反例。

标签: java exception exception-handling


【解决方案1】:

在 Java 6 中,没有比您已经建议的更有吸引力的选项了。

但是 Java 7 有一个 multi-catch 可以使用的语句:

catch(IllegalArgumentException | IllegalAccessException | IOException exception) {
    handleException(e);
}

【讨论】:

    【解决方案2】:

    我觉得在你的情况下,第二个选项就可以了。如果每种情况的异常处理都相同,则无需使代码过于复杂。

    【讨论】:

    • 这样,您将屏蔽所有未检查的异常。当你做那种事情时,上帝会哭泣。
    【解决方案3】:

    在 Java 7 中,有一个新的优秀的解决方案:你可以这样写:

    try{
    
        // do something
        // this piece of code throws several checked exceptions.
    
    } catch (IllegalArgumentException | IllegalAccessException | InvocationTargetException e) {
        handleException(e);
    } catch ...
    

    在较旧的 Java 版本中,捕获常见的子类——Exception 就是其中的一个例子——确实不是一个坏主意。 总是不加考虑地这样做是不好的,但如果你考虑过并选择它作为最佳解决方案,那么这样做是可以的。

    【讨论】:

      【解决方案4】:

      与 Java 6 或更低版本无关。

      使用 java 7,您可以执行以下操作:

      catch(InstantiationException | IOException | NoSuchFieldException exception) {
              // handle our problems here.
      }
      

      在 java 6 中,另一个“坏习惯”(但可能对您有用)可能是:

      catch (Exception e) {
         if(! e instanceof RuntimeException) // Only non-checked exceptions!
             throw e;
         handleException(e) // All checked exception.
      }
      

      问题:您正在使用 instanceof。但是你的代码看起来更好......

      【讨论】:

        【解决方案5】:

        这是检查异常如何让 Java 程序员的生活变得悲惨的另一个例子。仅仅因为一段代码可以引发检查异常,那么该特定代码很可能不是您想要处理它们的地方。如果您的应用设计良好,那么您已经有了一个中心位置,即异常屏障,您可以在其中处理(记录)您的异常。如果是这种情况,那么您应该将所有这些异常包装到 RuntimeException 中并将它们传递给屏障。在这种情况下,这是处理代码:

        try {
          // do stuff
        } catch (RuntimeException e) { 
          throw e; 
        } catch (Exception e) { 
          throw new RuntimeException(e); 
        }
        

        【讨论】:

          【解决方案6】:

          你们觉得这个解决方案怎么样?

          try {
              // some code that might throw an exception.
          } catch (Exception e) {
              if(e instanceof RuntimeException){
                  throw (RuntimeException) e;
              }
              // log exception
          }
          

          优点:

          1. 代码更少,可以为所有检查的异常保持相同的异常处理逻辑。
          2. 不处理运行时异常和错误。抓住它们,又把它们扔回去。

          缺点:

          1. 不要确认最佳实践检查,因为它仍然捕获异常。 (但要注意捕获运行时异常的情况,尽管检查样式可能会失败。)
          2. 向下转换为 RuntimeException 的任何可能的副作用?

          【讨论】:

            【解决方案7】:

            看起来 Java 7 团队的人听到了你的抱怨 :-) http://www.oracle.com/technetwork/articles/java/java7exceptions-486908.html

            【讨论】:

              【解决方案8】:

              您的代码看起来像您打算这样做:

              try{
                  // do something very bad
              } catch (Throwable e) {
                  handleException(e);
              }
              

              这不仅可以捕获所有异常,还可以捕获错误 - 可能在 try/catch 块中抛出的所有内容。

              捕获所有异常并让所有错误过去很少是正确的做法,但捕获一长串任意选择的不相关异常则更不可能是正确的做法。

              您的例外列表看起来相当可疑。 IE。为什么你会捕捉到 IllegalArgumentException 而不是 NullPointerException 或 ClassCastException,它们在语义上处于相似的级别。而且你似乎是在结合IO使用Reflection,所以你可能还要处理NoClassDefFoundError、ExceptionInInitializerError等错误。 StackOverflowError 甚至 OutOfMemoryError 呢...

              【讨论】:

              • 我使用的例外只是为了解释场景。这些不是我从代码中看到的“实际”异常。
              猜你喜欢
              • 2017-12-08
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2013-09-07
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多