【问题标题】:order in multi-catch exception handler多捕获异常处理程序中的顺序
【发布时间】:2015-10-02 23:28:46
【问题描述】:
我知道从 Java 7 开始你就可以使用multi-catch,但我想知道它的异常顺序是否像以前的 Java 版本一样重要?例如,我输入 Exception ,然后输入 SQLException 和 IOException ?
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 已经涵盖了它的子类 IOException 和 SQLException。
因此,如果您希望对所有这些异常类型进行相同的处理,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 比其他人更客观,因此应该是您处理的最后一个异常。
IOException 和 SQLException 没有可比性,因此,您可以随心所欲地处理它们。
所以,顺序应该是:
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);
}