: (1) 一个我们不能捕获的错误(例如,由客户程序员接收传递给自己方法的一个空句 柄) 。 (2) 作 为 一 名 程 序 员 , 一 个 应 在 自 己 的 代 码 中 检 查 的 错 误 ( 如 ArrayIndexOutOfBoundException,此时应注意数组的大小) 。 可以看出,最好的做法是在这种情况下违例,因为它们有助于程序的调试。 另外一个有趣的地方是,我们不可将 Java 违例划分为单一用途的工具。的确,它们设 计用于控制那些讨厌的运行期错误——由代码控制范围之外的其他力量产生。 但是, 它也特 别有助于调试某些特殊类型的编程错误,那些是编译器侦测不到的。 覆盖一个方法时,只能产生已在方法的基础类版本中定义的违例。这是一个重要的限制,因 为它意味着与基础类协同
工作的代码也会自动应用于从基础类衍生的任何对象 (当然, 这属 于基本的 OOP 概念) ,其中包括违例。 下面这个例子
演示了强加在违例身上的限制类型(在编译期) : //: StormyInning.Java // Overridden methods may throw only the // except
ions specified in their base-class // versions, or exceptions derived from the // base-class exceptions. class BaseballException extends Exception {} class Foul extends BaseballException {} class Strike extends BaseballException {} abstract class Inning { Inning() throws BaseballException {} void event () throws BaseballException { // Doesn't actually have to throw anything } abstract void atBat() throws Strike, Foul; void walk() {} // Throws nothing } class StormException extends Exception {} class RainedOut extends StormException {} class PopFoul extends Foul {} interface Storm { void event() throws RainedOut; void rainHard() throws RainedOut; } public class StormyInning extends Inning implements Storm {
// OK to add new exceptions for constrUCtors, // but you must deal with the base constructor // exceptions: StormyInning() throws RainedOut, BaseballException {} StormyInning(String s) throws Foul, BaseballException {} // Regular methods must conform to base class: //! void walk() throws PopFoul {} //Compile error // Interface CANNOT add exceptions to existing // methods from the base class: //! public void event() throws RainedOut {} // If the method doesn't already exist in the // base class, the exception is OK: public void rainHard() throws RainedOut {} // You can choose to not throw any exceptions, // even if base version does: public void event() {} // Overridden methods can throw // inherited exceptions: void atBat() throws PopFoul {} public static void main(String[] args) { try { StormyInning si = new StormyInning(); si.atBat(); } catch(PopFoul e) { } catch(RainedOut e) { } catch(BaseballException e) {} // Strike not thrown in derived version. try { // What happens if you upcast? Inning i = new StormyInning(); i.atBat(); // You must catch the exceptions from the // base-cla