1.异常分类
异常的对象都是派生于Throwable类的一个实例。
在throwable的下一层,立即分解为两个分支:Error,Exception
Error类层次结构描述了Java运行时系统的内部错误和资源耗尽错误。应用程序不应该抛出这种类型的对象。这种情况很少出现。
Exception层次又分解为两个分支:一个分支派生于RuntimeException;另一个分支包含其他异常。(由程序错误导致的异常输入RuntimeException;程序没问题,由于I/O错误这类问题导致属于其他异常)
派生于RuntimeException的异常包含下面几种情况:
- 错误的类型转换
- 数组访问越界
- 访问null指针
- 试图在文件尾部后面读取数据
- 试图打开一个不存在的恩建
- 试图根据给定的字符串查找class对象,但是这个字符串表示的类并不存在
派生于Error类或者RuntimeException类的所有异常称为非受查异常(unchecked),其他所有异常称为受查异常(checked)
2.声明受查异常
在遇到以下情况时应该抛出异常:
- 在调用一个抛出 受查异常的方法,例如FileInputStream构造器
- 程序运行过程中发现错误,并利用throw语句抛出一个受查异常
- 程序出现错误,例如a[-1]会抛出一个ArrayIndexOutBoundsException这样的非受查异常
- Java虚拟机和运行库出现的内部错误
public FileInputStream(String name) throws FileNotFoundException//标准库中的声明
3.如何抛出异常
首先要决定一个抛出什么异常。第一反应是IOException,仔细读过Java api 文档之后会发现EOFException更合适(在输入过程中,遇到一个未预期的EOF后的信号)(EOF指end of file)
String readData(Scanner in) throws EOFException{ ... while(...){ if(!in.hasNext()){ if(n<len) throw new EOFException(); } } return s; }
对于一个已经存在的异常,只需要:
1.找到合适的异常类
2.创建这个类的对象
3.将对象抛出
4.创建异常类
在程序中,可能会遇到任何标志异常类都没有能够充分描述的问题。在这种情况下就只能创建自己的异常类了。
只需要定义一个派生于Exception的类,或者派生于Exception子类的类。习惯上,定义的类应该包含两个构造器,一个是默认的构造器,另一个是带有详细描述信息的构造器。
//自己定义的异常 class FileFormatException extends IOException{ public FileFormatException(){} public FileFormatException(String gripe){ super(gripe); } } String readData(BufferedReader in) throws FileFormatException{ ... while(...){ if(ch == 1){ if(n<len) throw new FileFormatException(); } } return s; }
5.捕获异常
如果某个异常发生的时候没有捕获,那程序就会终止执行,并在控制台打印出异常信息。
要想捕获异常,就要设置try/catch语句块。最简单的try/catch语句块如下:
try{ //code //more code }catch{ //handler for this type }
如果在try语句块中的任何代码抛出一个在catch子句中说明的异常类,那么
- 程序将跳过try语句块的其余代码
- 程序将执行catch子句中的处理代码
public void read(String filename){ try{ InputStream in = new FileInputStream(filename); //可能抛出IOException int b; while((b=in.read())!=-1){ //... } }catch(IOException exception){ exception.printStackTree(); } }
try{ //... }catch(FileNotFoundException e){ //... }catch(UnknownHostException e){ //... }catch(IOException e){ //... }
Finally子句
InputStream in = new FileInputStream(...); try{ // 1 code that might throw exceptions // 2 }catch(IOException e){ // 3 show error message // 4 }finally{ // 5 in.close(); } //6
以上代码可能遇到3种情况: