您的位置:首页 > 编程语言 > Java开发

java炒冷饭系列06 异常匹配

2017-06-20 06:36 120 查看

前言

抛出异常的时候,异常处理系统会按照代码的书写顺序找出“最近”的处理程序。找到匹配的处理程序之后,它就认为异常将得到处理,然后就不再继续查找。

查找的时候并不要求抛出的异常同处理程序所声明的异常完全匹配。派生类的对象也可以匹配其基类的处理程序,你像这样:

class Annoyance extends Exception {

}
class Sneeze extends Annoyance {

}
public class Human {
public static void main(String[] args) {
try {
throw new Sneeze();
} catch (Sneeze sneeze) {
System.out.println("Caught Sneeze");
} catch (Annoyance annoyance) {
System.out.println("Caught Annoyance");
}

try {
throw new Sneeze();
} catch (Annoyance annoyance) {
System.out.println("Caught Annoyance");
}

}
}


Sneeze异常会被第一个匹配的catch子句捕获,也就是程序里的第一个。然而如果将这个catch子句删掉,只留Annoyancecatch子句,该程序仍然能运行,因为这次捕获的是Sneeze的基类。换句话说,catch(Annoyance e)会捕获Annoyance以及所有从它派生的异常。这一点非常有用,因为如果决定在方法里加上更多派生异常的话,只要客户程序员捕获的是基类异常,那么它们的代码就无需更改。

如果把捕获基类的catch子句放在最前面,以此想把派生类的异常全给“屏蔽”掉,就像这样:

try{
throw new Sneeze();
}catch(Annoyance a){
}catch(Sneeze s){
}


这样编译器就会发现Sneezecatch子句永远也得不到执行,因此它会向你报告错误。

这里还有个小小的练习:建立一个三层的异常继承体系,然后创建基类A,它的一个方法能抛出异常体系的基类异常。让B继承A,并且覆盖这个方法,让它抛出第二层的异常。让C继承B,再次覆盖这个方法,让它抛出第三层的异常。在main()里创建一个C类型的对象,把它向上转型为A,然后调用这个方法。

我给的答案

class Ea extends Exception {

}

class Eb extends Ea {

}

class Ec extends Eb {

}
public class CA {
public void method() throws Ea{
throw new Ea();
}

public static void main(String[] args) throws Ea {
CA ca = new CC();
ca.method();
}
}

class CB extends CA{
public void method() throws Eb{
throw new Eb();
}
}

class CC extends CB {
public void method() throws Ec {
throw new Ec();
}
}


这个练习也证明了

多态,虽然main方法处声明了Ea异常,但是实现上抛出的是其子类Ec异常

参考文献

《java编程思想》12.11异常匹配
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: