抛出异常的时候,异常处理系统会按照你书写代码的顺序找出“最近”的处理程序。找
到匹配的处理程序之后,它就认为异常将得到处理,然后就不再继续查找。
查找的时候并不要求抛出的异常同处理程序所声明的异常完全匹配。派生类的对象也可
以匹配处理程序中声明的基类,就像这样:
//: c09:Human.java
// Catching exception hierarchies.
import com.bruceeckel.simpletest.*;
class Annoyance extends Exception {}
class Sneeze extends Annoyance {}
public class Human {
private static Test monitor = new Test();
public static void main(String[] args) {
try {
throw new Sneeze();
} catch(Sneeze s) {
System.err.println("Caught Sneeze");
} catch(Annoyance a) {
System.err.println("Caught Annoyance");
}
monitor.expect(new String[] {
"Caught Sneeze"
});
}
} ///:~
Sneeze 会被第一个匹配的 catch 子句捕获,也就是程序里的第一个。然而如果你将这
个 catch 删掉,只留下:
try {
throw new Sneeze();
} catch(Annoyance a) {
System.err.println("Caught Annoyance");
}
该程序仍然能运行,因为这次捕获的是 Sneeze 的基类。换句话说,catch(Annoyance
e)会捕获 Annoyance 以及所有从它派生的异常。这一点非常有用,因为如果你要在方
法里加上更多派生异常的话,只要客户程序员捕获的是基类异常,那么它们的代码就无
需更改。
如果你把捕获基类的 catch 子句放在最前面,就会把派生类的异常全给“屏蔽”掉,像
这样:
try {
throw new Sneeze();
} catch(Annoyance a) {
System.err.println("Caught Annoyance");
} catch(Sneeze s) {
System.err.println("Caught Sneeze");
}
到匹配的处理程序之后,它就认为异常将得到处理,然后就不再继续查找。
查找的时候并不要求抛出的异常同处理程序所声明的异常完全匹配。派生类的对象也可
以匹配处理程序中声明的基类,就像这样:
//: c09:Human.java
// Catching exception hierarchies.
import com.bruceeckel.simpletest.*;
class Annoyance extends Exception {}
class Sneeze extends Annoyance {}
public class Human {
private static Test monitor = new Test();
public static void main(String[] args) {
try {
throw new Sneeze();
} catch(Sneeze s) {
System.err.println("Caught Sneeze");
} catch(Annoyance a) {
System.err.println("Caught Annoyance");
}
monitor.expect(new String[] {
"Caught Sneeze"
});
}
} ///:~
Sneeze 会被第一个匹配的 catch 子句捕获,也就是程序里的第一个。然而如果你将这
个 catch 删掉,只留下:
try {
throw new Sneeze();
} catch(Annoyance a) {
System.err.println("Caught Annoyance");
}
该程序仍然能运行,因为这次捕获的是 Sneeze 的基类。换句话说,catch(Annoyance
e)会捕获 Annoyance 以及所有从它派生的异常。这一点非常有用,因为如果你要在方
法里加上更多派生异常的话,只要客户程序员捕获的是基类异常,那么它们的代码就无
需更改。
如果你把捕获基类的 catch 子句放在最前面,就会把派生类的异常全给“屏蔽”掉,像
这样:
try {
throw new Sneeze();
} catch(Annoyance a) {
System.err.println("Caught Annoyance");
} catch(Sneeze s) {
System.err.println("Caught Sneeze");
}
这样编译器就会发现 Sneeze 的 catch 子句永远也得不到执行,因此它会向你报告错误