java异常处理中捕获多个异常时为什么习惯于将Exception的子类放在前面而父类放在后面?

首先,你说的这个情况叫“异常屏蔽”现象。


假设有两种异常:BaseExceptionDerivedException。Java里每种异常都是一个类。假设前者是基类,后者是前者的派生类。就像这样,

BaseException extends Exception {}
DerivedException extends BaseException {}
这时候如果我先尝试捕获BaseException,那所有的异常都会被它捕获,后面捕获DerivedException的尝试就会被彻底“屏蔽”。永远不会被触发。
try{
    throw new DerivedException();
}catch(BaseException be){
    //...
}catch(DerivedException de){    //彻底被屏蔽
   //...
}

发生这种情况,是由Java的异常匹配机制决定的。异常匹配就是指,抛出的异常到底由哪个异常处理单元(handler)处理。主要有两大原则:
  1. 就近匹配原则:找到离异常异常抛出点最近的处理单元,叫被“捕获”,然后就不再往下找。
  2. 向上转型原则:一个特定类型的异常处理单元,可以捕捉它本身以及所有从它派生的异常。

所以根据以上两个原则,再看上面这段代码,就很清楚了,DerivedException异常抛出,根据就近匹配原则,找到最近的catch(BaseException be)处理单元。然后又根据向上转型原则BaseException处理单元可以处理它的派生异常DerivedException。然后这个异常就被捕获处理了,不在继续往下找处理单元。于是第二个处理单元就悲剧了。

这就好比你用两个盆子接水,大盆子在上,小盆子在下,那小盆子自然就一滴水也接不到。是不是这个道理?


转载自:https://www.zhihu.com/question/29472761

阅读更多
换一批

没有更多推荐了,返回首页