异常
//《java核心编程》读书笔记
- 异常
Exception分解成两个分支:RuntimeException,其他异常。
RuntimeException:程序的错误导致的异常。包含以下几种情况:
1、错误的类型转换
2、数组访问越界
3、访问空指针
不是派生于RuntimeException包含以下几种情况
1、试图在文件尾部后读取数据
2、试图打开一个错误格式的URL
3、试图根据给定的字符串查找class,而该字符串表示的类不存在
“如果存在RuntimeException异常,那么就一定是你的问题”
在自己编写方法时,并不需要将所有可能的异常都要进行声明。需要记住以下几种情况需要抛出异常:
1、调用一个抛出已检查异常的方法,例如,FileInputStream构造器。
2、程序运行过程中发现错误,并利用throw语句抛出一个已检查的异常。w
3、程序出现错误,例如a[-1]=0会抛出一个ArrayIndexOutOfBoundsException这样的未检查异常
4、java虚拟机和运行时库出现的内部异常
一个方法必须声明所有可能抛出的已检查异常,而未检查异常要么不可控制如error,要么没必要声明如RuntimeException异常。
- 如何抛出异常
假设一个名为readData的方法正在读取一个首部具有下列信息的文件:Content-length:1024;
然而读了732个字符就结束了,这不是正常情况,需要抛出一个异常。首先需要知道抛出什么异常。将上述归结为IOException是个很好的选择,但是查看API文档,发现EOFException更好。throw new EOFException()
String readData(Scanner in) throws EOFException { ... while(...){ if(!in.hasNext){ if(n<len){ throw new EOFException; } .... } } return s; }
对于一个已经存在的异常类,将其抛出很容易。
1、找到合适的异常类
2、创建这个类的对象
3、将对象抛出
-
捕获异常
简单的try语句块:
try{ code more code more code } catch(ExceptionType e) { handler for this type }
如果在try语句块中抛出一个在catch子句中说明的异常类,那么
1、程序就跳过try语句的其他代码
2、程序执行catch语句的处理代码
finally语句
当代码抛出一个异常时,会终止方法中的剩余代码处理,并退出这个代码的执行。如果方法获取了本地资源,在退出方法之前没被收回,就产生了一个资源回收的问题。
一种解决方法捕获并重新抛出所有异常。但这种方法比较乏味。要在两个地方清除本地资源。
另一种是使用finally语句。不管是不是有异常被捕获,finally语句都会被执行。下面程序释放所有环境中的Graphic调用。
Graphics g=image.getGraphics(); try { try{ //code may throw exception } finally{ g.dispose(); } } catch(IOException e){ //show error detail }
上面代码有麻烦之处。当关闭操作有异常时,也会抛出异常。如果异常和try中的相同,会将其覆盖。丢失原来的异常,转而抛出关闭操作的异常。
-
使用异常机制的建议
1、异常处理不能代替简单的测试
2、不要过分地细化异常
3、利用异常的层次结构
4、不要压制异常
5、在检测错误时,“苛刻”要比放任更好
6、不要羞于传递异常