Java中的异常处理
以下内容为我读《TIJ》中第13章的读书笔记:
一、 基本概念
? ? ? Java的基本理念是“结构不佳的代码不能运行”。Java属于强类型、强检查语言,即编译器会处理大量的的安全和基本的语法错误问题。但还是有一些错误巧妙地隐藏了起来,只有在运行时才被发现。
? ? ? 老式的程序设计语言,例如C,的多重错误处理模式,往往建立在约定俗成的基础上,并不是语言的一部分。大致上,通过一个函数返回某个特殊值或设置某个标志来通知接收者,出错了。这就把错误的发出与程序的正确运行含混地绑定在了一起。这让程序员感到厌烦,于是很多时候拒绝针对所有的可能发生错误的位置进行细致地检查,如果程序员真的那么做了,那么实际上整个程序的可读性还会变得更差。
? ? ? 于是产生了这样一种做法,在“正常执行中做什么事”的代码中抛出一个异常,交给“出了问题怎么办”的代码。这就实现了隔离。使得代码井井有条,可读性、可维护性更好。
? ? ? 异常处理的实现,可以上溯20世纪60年代。C++的异常处理机制基于Ada,Java的异常处理则建立在C++的基础上(尽管看上去更像Object Pascal)。
?
?
?
? ? ?异常的涵义:我对此感到意外,但我不知道该如何处理它。
?
?二、 ? ?基本异常
?
?
? ? ? 1 抛出异常对象的方式和返回普通对象的方式差不多。只不过返回普通对象的方式是return new 构造器,而抛出异常对象的方式是throw new 构造器(一切Throwable类型,而不仅仅是Exception类型)。异常代表的思想是,不允许程序沿着某条路经继续走下去。实际上这样看来,抛出异常也是一种返回机制,因为程序退出了。
? ? ?识别异常有两种形式: 通过无参构造器返回的异常类型确认;通过字符串参数构造器携带的字符串来确认。
三、 ?捕获异常
?
? ? ?一个熟悉的概念,可能发生异常的代码段称为guarded region--监控区域。?
? ? 即
[java]?view plaincopy
- public?class?Ex5?{??
- ????private?static?int[]?ia?=?new?int[2];??
- ????static?int?x?=?5;?????
- ????public?static?void?main(String[]?args)?{??
- ????????while(true)?{??
- ????????????try?{??
- ????????????????ia[x]?=?1;??
- ????????????????System.out.println(ia[x]);??
- ????????????????break;????
- ????????????}?catch(ArrayIndexOutOfBoundsException?e)?{??
- ????????????????System.err.println(??
- ????????????????????"Caught?ArrayIndexOutOfBoundsException");??
- ????????????????????e.printStackTrace();??
- ????????????????x--;??
- ????????????}?finally?{??
- ????????????????System.out.println("Are?we?done?yet?");???????
- ????????????}??
- ????????}??
- ????????System.out.println("Now,?we're?done.");??
- ????}?????
- }??
?
?
结果:
?
[html]?view plaincopy
- Caught?ArrayIndexOutOfBoundsException??
- Are?we?done?yet???
- Are?we?done?yet???
- java.lang.ArrayIndexOutOfBoundsException:?5??
- ????at?my.test.Ex5.main(Ex5.java:9)??
- Caught?ArrayIndexOutOfBoundsException??
- java.lang.ArrayIndexOutOfBoundsException:?4??
- ????at?my.test.Ex5.main(Ex5.java:9)??
- Caught?ArrayIndexOutOfBoundsException??
- java.lang.ArrayIndexOutOfBoundsException:?3??
- ????at?my.test.Ex5.main(Ex5.java:9)??
- Are?we?done?yet???
- Caught?ArrayIndexOutOfBoundsException??
- java.lang.ArrayIndexOutOfBoundsException:?2??
- ????at?my.test.Ex5.main(Ex5.java:9)??
- Are?we?done?yet???
- 1??
- Are?we?done?yet???
- Now,?we're?done. ?
?
?
? ? ? 关于trycatch语句块的一些思考:
?
?
?
? ? ? 实际上我们不管在try里面手动throw 一个异常,虚拟机都有可能自动throw抛出一个异常。那我们手动抛出又有什么意义呢?手动抛出就要求我们严格管理我们的异常。
? ? ? 根据《TIJ》:
? ? ? 第一个例子,
?
?
??
?
?
第三个例子,LoggingExceptions2
?
? ? ??import java.io.*;
?第五个例子,ExceptionMethods
?
?
??
第六个例子,打印栈帧轨迹
?
?
第七个例子,异常链
?
第八个例子,finally引发的异常丢失
?
第九个例子, 异常的限制
?
?
第十个例子,构造器与异常
?
?
?
?
?
三、最后的思考
?
?
? ? ? 强制实施的checked exception 是Java长于C++的地方。因为Java完全摒弃了通过不同的返回值或者设定标志位的方法来保留错误信息的方式,而统一为使用异常来报告。但是这也带来了一些问题,就是我们必须在可能抛出异常的地方用使用catch语句。值得庆幸的是,我们可以在外层方法生命的地方使用Throws 关键字把这些错误丢给最外层,一层一层,甚至直接丢给控制台。
? ? ? 勤用Throws关键字是个好习惯。
?