并不一定非要使用Java违例这一点必须掌握因为经常都需要创建自己的违例以便指出自己的库可能生成的一个特殊错误——但创建Java分级结构的时候这个错误是无法预知的 为创建自己的违例类必须从一个现有的违例类型继承——最好在含义上与新违例近似继承一个违例相当简单 //: Inheritingjava // Inheriting your own exceptions class MyException extends Exception { public MyException() {} public MyException(String msg) { super(msg); } } public class Inheriting { public static void f() throws MyException { Systemoutprintln( Throwing MyException from f()); throw new MyException(); } public static void g() throws MyException { Systemoutprintln( Throwing MyException from g()); throw new MyException(Originated in g()); } public static void main(String[] args) { try { f(); } catch(MyException e) { eprintStackTrace(); } try { g(); } catch(MyException e) { eprintStackTrace(); } } } ///:~ 继承在创建新类时发生 class MyException extends Exception { public MyException() {} public MyException(String msg) { super(msg); } } 这里的关键是extends Exception它的意思是除包括一个Exception的全部含义以外还有更多的含义增加的代码数量非常少——实际只添加了两个构建器对MyException的创建方式进行了定义请记住假如我们不明确调用一个基础类构建器编译器会自动调用基础类默认构建器在第二个构建器中通过使用super关键字明确调用了带有一个String参数的基础类构建器 该程序输出结果如下 Throwing MyException from f() MyException at Inheritingf(Inheritingjava:) at Inheritingmain(Inheritingjava:) Throwing MyException from g() MyException: Originated in g() at Inheritingg(Inheritingjava:) at Inheritingmain(Inheritingjava:) 可以看到在从f()掷出的MyException违例中缺乏详细的消息 创建自己的违例时还可以采取更多的操作我们可添加额外的构建器及成员 //: Inheritingjava // Inheriting your own exceptions class MyException extends Exception { public MyException() {} public MyException(String msg) { super(msg); } public MyException(String msg int x) { super(msg); i = x; } public int val() { return i; } private int i; } public class Inheriting { public static void f() throws MyException { Systemoutprintln( Throwing MyException from f()); throw new MyException(); } public static void g() throws MyException { Systemoutprintln( Throwing MyException from g()); throw new MyException(Originated in g()); } public static void h() throws MyException { Systemoutprintln( Throwing MyException from h()); throw new MyException( Originated in h() ); } public static void main(String[] args) { try { f(); } catch(MyException e) { eprintStackTrace(); } try { g(); } catch(MyException e) { eprintStackTrace(); } try { h(); } catch(MyException e) { eprintStackTrace(); Systemoutprintln(eval() = + eval()); } } } ///:~ 此时添加了一个数据成员i同时添加了一个特殊的方法用它读取那个值也添加了一个额外的构建器用它设置那个值输出结果如下 Throwing MyException from f() MyException at Inheritingf(Inheritingjava:) at Inheritingmain(Inheritingjava:) Throwing MyException from g() MyException: Originated in g() at Inheritingg(Inheritingjava:) at Inheritingmain(Inheritingjava:) Throwing MyException from h() MyException: Originated in h() at Inheritingh(Inheritingjava:) at Inheritingmain(Inheritingjava:) eval() = 由于违例不过是另一种形式的对象所以可以继续这个进程进一步增强违例类的能力但要注意对使用自己这个包的客户程序员来说他们可能错过所有这些增强因为他们可能只是简单地寻找准备生成的违例除此以外不做任何事情——这是大多数Java库违例的标准用法若出现这种情况有可能创建一个新违例类型其中几乎不包含任何代码 //: SimpleExceptionjava class SimpleException extends Exception { } ///:~ 它要依赖编译器来创建默认构建器(会自动调用基础类的默认构建器)当然在这种情况下我们不会得到一个SimpleException(String)构建器但它实际上也不会经常用到 |