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
对于一个已经存在的异常,只需要:
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
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种情况: