异常的继承关系图:
Exception的其中一个子类RuntimeException(被0除,数组越界。。。)是经常出的异常,可以不捕获;另一个子类异常(如IOException)必须捕获try{...}catch{....}。
自定义异常
1)从Exception类或者它的子类派生 一个子类即可
2)习惯上,定义的类应该包含2个构造器:一个是默认的构造器,另一个是带有详细信息的构造器。
使用异常机制的建议
1)要避免使用异常处理代替错误处理,这样会降低程序的清晰性,并且效率低下。
2)不要进行小粒度的异常处理(即不要写N多个try,catch)--应将整个任务包装在一个Try语句块中。
3)异常往往在“高层”中处理
总结:
1.一个图
2.五个关键字
try,catch
try{
//可能抛出异常的语句;
}
catch(someExceptin1 e){
}
catch(someExceptin2 e){
}
...
在catch中声明的异常对象封装了异常事件发生的信息,在catch语句块中可以使用这个对象的一些方法获取这些信息。
例如:
getMessage()方法,用来得到有关异常事件的信息。
printStackTrace()方法,用来跟踪异常事件发生时执行堆栈的内容。
finally语句为异常处理提供一个统一的出口,使得在控制流程转到程序的其他部分以前,能够对程序的状态作统一的管理。
无论try所指定的程序块中是否抛出异常,finally所指定的代码都要被执行。
通常在finally语句中可以进行资源的清楚工作,如:
1)关闭打开的文件
2)删除临时文件
3)关闭各种资源
4)...
throws 声明方法可能抛出的异常,向上抛出异常,调用该方法时需要处理这种异常,也可以继续抛出异常。
import java.io.*;
public class Test01 {
public static void main(String[] args){
Test01 t = new Test01();
t.f2();
}
public void f() throws FileNotFoundException,IOException{
FileInputStream in = new FileInputStream("C:\\Users\\tcj\\Desktop\\a.txt");
int b;
b = in.read();
while(b != -1){
System.out.print((char)b);
in.read();
}
}
public void f2(){
try {
f();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
throw语句抛出异常
3)先逮小的,再逮大的
4)异常和重写的关系;重写的方法必须抛出与原方法类型一致的异常或者不抛出异常
5)自定义异常
下面是一个异常测试小程序:
import java.io.*;
public class TestException {
public static void main(String[] args){
FileInputStream in = null;
try{
in = new FileInputStream("C:\\Users\\tcj\\Desktop\\a.txt");
int b ;
b = in.read();
while(b != -1){
System.out.print((char)b);
b = in.read();
}
}catch(FileNotFoundException e){
e.printStackTrace();
}
catch(IOException e){
System.out.println(e.getMessage());
}
finally{
try{
in.close();
}catch(IOException e){
e.printStackTrace();
}
}
}
}