为什么我不能多次捕获异常?

时间:2014-09-30 08:26:52

标签: java exception language-lawyer

JLS 8, 14.20

  

try语句执行一个块。如果抛出一个值并尝试   语句有一个或多个可以捕获它的catch子句   控制权将转移到第一个此类捕获条款

看起来我可能有两个相同异常类型的catch子句。但是当我尝试这个时,我会收到编译时错误。

public static void main (String[] args) throws java.lang.Exception
{
    try{
    } catch(RuntimeException ioe){
    } catch(NumberFormatException e){ //Already caught
    } 
}

IDEONE

你能用JLS解释一下吗?

4 个答案:

答案 0 :(得分:2)

NumberFormatException是RuntimeException的特化,因此您的NumberFormatException将被第一个语句捕获。但是,您可以切换这两个catch子句的顺序;但请记住,只有一个将被执行:

  • 如果异常具有此类型的NumberFormatException子句
  • 所有其他类型的RuntimeException的RuntimeException子句

至于为什么就是这样...那就是语言的设计方式。如果执行了所有匹配的catch块,那么正确处理错误将非常困难。

答案 1 :(得分:1)

因为RunTimeException是NumberFormatException的基类。的 http://docs.oracle.com/javase/7/docs/api/java/lang/NumberFormatException.html

答案 2 :(得分:1)

从获取的异常的层次结构中得到的编译器错误。

NumberFormatException extends IllegalArgumentException extends RuntimeException

将catch块视为安全网。 NumberFormatException网络非常小,因为它是更高层次结构异常的特例。 RuntimeException网是最大可能之一,它将捕获此级别上的任何内容(Exception和Throwables除外,它们是"上级")。你所做的是将小网放在大网之下。所以编译器很有礼貌,可以提示你永远不会达到较小的网络。

(我知道metapher不是100%精确,但在这种情况下工作正常。)

如果先捕获NumberFormatException然后再运行RuntimeException,编译器会很乐意同意! :-) 您也可以从第一个块重新抛出捕获的异常。

答案 3 :(得分:1)

NumberFormatExceptionRuntimeException的子类型当您抓住RuntimeException时,它会抓住所有类型的RuntimeException,包括NumberFormatException。这就是为什么它已经被抓住了。