【问题标题】:order in multi-catch exception handler多捕获异常处理程序中的顺序
【发布时间】:2015-10-02 23:28:46
【问题描述】:

我知道从 Java 7 开始你就可以使用multi-catch,但我想知道它的异常顺序是否像以前的 Java 版本一样重要?例如,我输入 Exception ,然后输入 SQLExceptionIOException

try {
      // execute code that may throw 1 of the 3 exceptions below.

} catch(Exception | SQLException | IOException e) {   
    logger.log(e);

}

还是我应该这样做?

try {

    // execute code that may throw 1 of the 3 exceptions below.

} catch(SQLException | IOException e) {
    logger.log(e);

} catch(Exception e) {
    logger.severe(e);
}

【问题讨论】:

    标签: java exception exception-handling multi-catch


    【解决方案1】:

    catch(Exception | SQLException | IOException e) 的单个 catch 块没有意义,因为 Exception 已经涵盖了它的子类 IOExceptionSQLException

    因此,如果您希望对所有这些异常类型进行相同的处理,catch(Exception e) 就足够了。

    如果您想对更通用的 Exception 进行不同的处理,您的第二个代码 sn-p 是有意义的,这里两个 catch 块的顺序很重要,因为您必须首先捕获更具体的异常类型。

    【讨论】:

      【解决方案2】:

      是的,顺序很重要,从子到父。

      更多信息请参考this

      异常变量是隐式最终的,因此我们不能分配 在 catch 块中将变量设置为不同的值。例如, 下面的代码sn -p会报编译错误

      } catch (IOException | SQLException ex) {
      
          ex = new SQLException();
      
      }
      

      编译器会抛出这个错误:multi-catch parameter ex may not be assigned

      不允许同时指定两个或多个例外 multi-catch 语句中的层次结构。例如,以下 代码 sn-p 将给出编译错误,因为 FileNotFoundException 是 IOException 的子类型

      } catch (FileNotFoundException | IOException ex) {
      
          LOGGER.log(ex);
      
      }
      

      编译器会抛出这个错误(无论顺序如何):multi-catch 语句中的替代项不能通过子类化来关联

      Exception 类是所有异常的超类型,因此我们也 写不出来

      } catch (IOException | Exception ex) {
      
          LOGGER.log(ex);
      
      }
      

      【讨论】:

        【解决方案3】:

        Java 中提供了多捕获功能,以消除两个不同层次异常中的代码重复。如果您出于这个原因使用它,则订购无关紧要。如果你在 multi catch 块中捕获父异常类Exception,则无需添加子异常IOException, SQLException 类。

        【讨论】:

          【解决方案4】:

          顺序很重要,因为如果您尝试首先捕获 Exception,而您的第二个捕获是针对 IOException,那么显然您将永远无法捕获第二个捕获。所以顺序必须是从最小的Exception到最大的。

          【讨论】:

            【解决方案5】:

            multicatch Exceptiontypes 由“OR”分隔,所以不,顺序无关紧要。

            如果您打算以同样的方式处理所有异常类型,则只应使用 multicatch,如果是这种情况,则顺序无关紧要。

            编辑:确实,如果类型在分层行中,则应仅捕获“替代”(在本例中为通用异常)类型。 不过,这与他们的顺序无关。

            【讨论】:

              【解决方案6】:

              异常有一些层次结构。 Exception e 比其他人更客观,因此应该是您处理的最后一个异常。

              IOExceptionSQLException 没有可比性,因此,您可以随心所欲地处理它们。

              所以,顺序应该是:

              try {
              
              // execute code that may throw 1 of the 3 exceptions below.
              
              } catch(SQLException | IOException e) {
                   logger.log(e);
              
              } catch(Exception e) {
                   logger.severe(e);
              }
              

              try {
              
              // execute code that may throw 1 of the 3 exceptions below.
              
              } catch(SQLException e) {
                   logger.log(e);
              
              } catch(IOException e){
                   logger.log(e);
              
              } catch(Exception e) {
                   logger.severe(e);
              }
              

              try {
              
              // execute code that may throw 1 of the 3 exceptions below.
              
              } catch(IOException e) {
                   logger.log(e);
              
              } catch(SQLException e){
                   logger.log(e);
              
              } catch(Exception e) {
                   logger.severe(e);
              }
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2017-05-02
                • 1970-01-01
                • 2014-09-02
                • 1970-01-01
                • 1970-01-01
                • 2011-08-17
                相关资源
                最近更新 更多