有时候只使用一个异常处理不完全解决程序中出现的异常,需要多个异常处理,这就需要多重catch来实现。
一段代码可能会生成多个异常当引发异常时,会按顺序来查看每个 catch 语句,并执行第一个类型与异常类型匹配的语句执行其中的一条 catch 语句之后,其他的 catch 语句将被忽略。
多重catch语法如下:
try{ //正常程序处理语句 } catch(ArrayIndexOutOfBoundsException e) { //系统子类异常 } catch(Exception e) { //系统基类异常 }
注意: 1. 一段代码可能会生成多个异常 2. 当引发异常时,会按顺序来查看每个 catch 语句,并执行第一个类型与异常类型匹配的语句 3. 执行其中的一条 catch 语句之后,其他的 catch 语句将被忽略。
特别注意:在一系列catch语句中,异常子类应该位于其父类之前。否则,不但会产生不能实现的代码,而且将发生编译错误。
如我们在上文实例中:0作为除数则会引发DivideByZeroException类型的异常,上例中的catch语句可以作如下修改:
catch(DivideByZeroException e) { System.Console.WriteLine("零不能作为除数!异常值为:\n{0}",e); } catch(Exception e) { System.Console.WriteLine("并非\""""零作为除数引发的异常\"!异常值为:\n{0}",e); }
为什么还要加上一个catch(Exception e)子句呢?原因很简单,catch(DivideByZeroException e)子句只能捕获特定的异常,try内的程序代码可能还会产生其它的异常,这些异常只能由catch(Exception e)来捕获了。
存在多个catch时,try块中出现异常后,系统将从距离try块最近的catch块中查找相应的异常处理语句,如果匹配成功,就执行catch块中的异常处理语句,执行完之后,不再执行其他catch块中的异常处理语句,这个查找过程是从上到下的,主要是检查catch后面括号中的异常对象是否和系统捕获到的异常兼容。上面语句中有两个catch块,其中后面一个异常处理中Exception是所有异常类的基类,其能够兼容任何异常对象。如果把Exception放在try后面的第一个catch块中,则其后面的所有catch语句不能被执行,所以通常把具体的异常放在前面,把基类放在最后的catch块中。
基类可以捕获所有异常,我们可能会想:既然基类可以捕获所有异常,是不是只写一个Exceotion就可以解决问题了呢?在实际应用中,一般不会这样处理。打一比方,一所综合性医院有很多科室,每个科专门处理不同的病情,眼科医生擅长眼睛方面疾病,可以把Exception看做全科医生,名个派生的基类分别属于不同的专业科室,去医院看病总是选择最匹配的科室,为眼睛首先会选择眼科,而不会去找全科医生,虽然全科医生也是可以治眼病,但是毕竟不够专业。在异常处理中,也是首先选择各个专业的异常类,Exception放在最后。 |