在Java中进行错误处理时,是否应该捕获Exception以捕获所有异常或单独捕获异常?

jos*_*nes 1 java exception

假设我有代码抛出许多不同的异常:

thisThrowsIllegalArgumentException("this is an illegal argument");
thisThrowsIOException("C:/Users/Admin/Documents/does-not-exist.txt");
thisThrowsIndexOutOfBoundsException(Integer.MAX_SIZE + 1);
thisThrowsNullPointerException(null);
...etc
Run Code Online (Sandbox Code Playgroud)

需要处理这些错误.所以,我有两个选择.我可以:

单独捕获每个异常,如下所示:

try {
    ...
} catch (IllegalArgumentException ex) {
    System.err.println("Something went wrong.");
} catch (IOException ex) {
    System.err.println("Something went wrong.");
} catch (IndexOutOfBoundsException) {
    System.err.println("Something went wrong.");
} catch (NullPointerException) {
    System.err.println("Something went wrong.");
}
Run Code Online (Sandbox Code Playgroud)

......或者Exception像一般人一样:

try {
    ...
} catch (Exception ex) {
    System.err.println("Something went wrong.");
}
Run Code Online (Sandbox Code Playgroud)

据我所知,在Java 7中,您可以简单地写:

try {
    ...
} catch (IllegalArgumentException | IOException | IndexOutOfBoundsException | NullPointerException ex) {
    System.err.println("Something went wrong.");
}
Run Code Online (Sandbox Code Playgroud)

但是,我被限制在Java 6中.

这是什么最好的做法?

Boh*_*ian 6

一般的做法:

  • 如果catch块正在处理问题,则捕获最窄的异常类
  • 如果调用者要处理问题,请声明throws.您可能会捕获(仍然尽可能最窄)并抛出特定于域的异常
  • 如果你无法解决问题,但是因为你的代码是调用堆栈中的顶层而没有"调用者",请捕获异常,因为你的代码是最后一次采取行动的机会


Bri*_*etz 6

捕获Exception应用程序代码通常是错误的.有时它是不可避免的,但如果它是可以避免的,你应该避免它.

注意:

try {
    ...
} catch (IllegalArgumentException ex) {
    System.err.println("Something went wrong.");
} catch (IOException ex) {
    System.err.println("Something went wrong.");
} catch (IndexOutOfBoundsException) {
    System.err.println("Something went wrong.");
} catch (NullPointerException) {
    System.err.println("Something went wrong.");
}
Run Code Online (Sandbox Code Playgroud)

try {
    ...
} catch (Exception ex) {
    System.err.println("Something went wrong.");
}
Run Code Online (Sandbox Code Playgroud)

做不同的事情!后者捕获所有RuntimeExceptions(未经检查的异常)以及您期望捕获的已检查异常!具有相同的语义,你必须赶上并重新抛出RuntimeException之前Exception,但随后仍必须明确处理要处理,这样的未检查异常:

try {
    ...
} catch (IllegalArgumentException ex) {
    System.err.println("Something went wrong.");
} catch (IndexOutOfBoundsException) {
    System.err.println("Something went wrong.");
} catch (NullPointerException) {
    System.err.println("Something went wrong.");
} catch (RuntimeException e) { 
    throw e; 
} catch (Exception e) {
    System.err.println("Something went wrong.");
}
Run Code Online (Sandbox Code Playgroud)

哪种方式失败了,你希望代码更紧凑.

您应该编写多异常catch并计划在升级到Java 7时合并catch子句(一个好的IDE将帮助您找到它们并为您转换它们.)