Java中捕获异常的顺序

Java中捕获异常的顺序,java,exception,Java,Exception,如果我没有弄错的话,应该首先捕获异常的子类。但是必须捕获任何RuntimeException和一个具体的检查异常,哪一个应该首先捕获 try { ... } catch(RuntimeException e) { ... } catch(IOException e) { ... } 这个订单对吗?或者它是正确的,但不是一个好的选项?编译器将接受的任何顺序都是正确的。顺序是任何首先匹配的,都会被执行 如果第一个捕获与异常匹配,它将执行,如果不匹配,则会不断尝试下一个捕获,

如果我没有弄错的话,应该首先捕获异常的子类。但是必须捕获任何RuntimeException和一个具体的检查异常,哪一个应该首先捕获

try {
    ...
} catch(RuntimeException e) {
    ...
} catch(IOException e) {
    ...
}

这个订单对吗?或者它是正确的,但不是一个好的选项?

编译器将接受的任何顺序都是正确的。

顺序是任何首先匹配的,都会被执行

如果第一个捕获与异常匹配,它将执行,如果不匹配,则会不断尝试下一个捕获,直到匹配一个或不匹配为止

因此,在捕获异常时,您希望始终首先捕获最具体的,然后是最通用的异常(如RuntimeException或Exception)。例如,假设您希望捕获该方法抛出的,但您的代码也可以抛出,下面是捕获异常的方法:

String s = null;
try {
  s.charAt(10);
} catch ( NullPointerExeption e ) {
  System.out.println("null");
  e.printStackTrace();
} catch ( StringIndexOutOfBoundsException e ) {
  System.out.println("String index error!");
  e.printStackTrace();
} catch ( RuntimeException e ) {
  System.out.println("runtime exception!");
  e.printStackTrace();
}
因此,按照这个顺序,我要确保异常被正确捕获,并且它们不会相互绊倒,如果它是NullPointerException它进入第一个捕获,如果StringIndexOutOfBoundsException它进入第二个,最后如果它是其他运行时异常(或从中继承,如IllegalArgumentException)它进入第三个捕获

您的案例是正确的,因为IOException继承自Exception,RuntimeException也继承自Exception,所以它们不会互相绊倒

首先捕获泛型异常,然后捕获它的一个后代,这也是一个编译错误,如:

try {
  // some code here
} catch ( Exception e) {
  e.printStackTrace();
} catch ( RuntimeException e ) { // this line will cause a compilation error because it would never be executed since the first catch would pick the exception
  e.printStackTrace();
}
因此,您应该先有子类,然后有父类异常

这个订单是正确的吗?还是正确的,但不是一个好的选择

两者都不是。正如其他答案所说,编译器应该告诉您,如果您将简单捕获按顺序放置,其中一个捕获会掩盖另一个捕获

但代码中还有另一个潜在问题:您是否真的应该捕获
RuntimeException
。问题是,未检查异常有许多源/原因,其中许多源/原因实际上是应用程序中的bug

在紧急停机过程中使用
catch
记录诊断是可以的,但是 如果您捕获并试图从
运行时异常中恢复,则需要小心不要将严重问题掩盖起来:

  • 无论发生什么情况,请确保记录异常及其堆栈跟踪

  • 考虑尝试恢复是否明智。如果您有未知错误,它可能会在触发异常之前造成不可预测的损坏。您无法知道应用程序是否可以恢复,或者尝试继续操作是否会造成更严重的损坏


同样的建议也适用于捕捉
异常
可丢弃的
/
错误
。而对于
可丢弃的
/
错误
更为关键,因为很可能已经发生了损坏的性质。

这是一个很好的观点。但是你说什么呢“并尝试从RuntimeException中恢复”?我没有尝试这样做,实际上不需要从RuntimeException中恢复。或者是吗?我所说的“尝试恢复”是指除了允许或导致应用程序退出以外的其他操作。不清楚您的代码是否会这样做。(这取决于所附代码中发生了什么。)无论如何,我并不是说你要这样做。相反,我提供的是一般性建议,只要你的代码捕捉到一个根异常类,这些建议就会适用。请解释一下。这里没有错误。其他两个答案都是一致的。如果你不同意,请明确地这样做,但要准备引用章节。你的答案对OP没有帮助,所有答案都没有帮助其他读者也有类似的问题。@user1170330当然有。你只需编译,阅读错误消息,然后进行相应的修复。几乎每个错误都可以在编译器的帮助下修复。那么为什么还要费心寻找帮助呢?@user1170330我完全同意。几乎每个错误都可以在编译器的帮助下修复。看这里当编译器没有帮助时,这是最后的手段。计算机程序员应该能够自己理解和纠正90%的编译错误;然后他们应该参考标准规范性参考;只有在必要时才应该寻求外部帮助。遗憾的是,这里有太多的成员颠倒了顺序:因此,这里有太多琐碎的问题。'Want to'与此无关。编译器强制执行正确的顺序。