异常思维导图
java异常处理.png
一、异常的种类
检查性异常:最具代表的检查性异常是用户错误或问题引起的异常,这是程序员无法预见的。例如要打开一个不存在文件时,一个异常就发生了,这些异常在编译时不能被简单地忽略。
运行时异常(非检查异常): 运行时异常是可能被程序员避免的异常。与检查性异常相反,运行时异常可以在编译时被忽略。
错误不是异常,而是脱离程序员控制的问题。错误在代码中通常被忽略。例如,当栈溢出时,一个错误就发生了,它们在编译也检查不到的。
二、基本异常
异常情形(exceptional condition):指当前方法或作用域继续执行的问题。
抛出异常执行的操作:
在堆中创建一个异常对象
终止当前执行路径,弹出对异常引用对象的引用
异常处理机制接管程序,交给异常处理程序处理。
异常处理机制:将程序从错误状态中恢复,使程序换种方式运行或继续执行下去。
抛出异常的简单例子:
if(t==null) thow new NullPointerException();
三、捕获异常
异常写法:使用try{}catch(Exception e){}finally{}
注:一个try代码块后面跟随多个catch代码块的情况就叫多重捕获。 如:
try{
// 程序代码
}catch(异常类型1 异常的变量名1){
// 程序代码
}catch(异常类型2 异常的变量名2){
// 程序代码
}catch(异常类型2 异常的变量名2){
// 程序代码
}
异常处理理论两种基本模型
终止模型:一旦异常抛出,就终止。
恢复模型:修正错误,然后重新调用方法来修正错误。
四、抛出异常(throws/throw关键字:)
解析:
如果一个方法没有捕获一个检查性异常,那么该方法必须使用throws 关键字来声明。throws关键字放在方法签名的尾部。 也可以使用throw关键字抛出一个异常,无论它是新实例化的还是刚捕获到的。
throws/throw关键字的区别:
throws是用来声明一个方法可能抛出的所有异常信息
throw则是指抛出的一个具体的异常类型
throw是语句抛出一个异常。
语法:throw (异常对象);
throw e;
throws是方法可能抛出异常的声明。(用在声明方法时,表示该方法可能要抛出异常)
语法:[(修饰符)](返回值类型)(方法名)([参数列表])[throws(异常类)]{......}
public void doA(int a) throws Exception1,Exception3{......}
五、finally关键字
解析:finally关键字用来创建在try代码块后面执行的代码块。 无论是否发生异常,finally代码块中的代码总会被执行
如:
try{
// 程序代码
}catch(异常类型1 异常的变量名1){
// 程序代码
}catch(异常类型2 异常的变量名2){
// 程序代码
}finally{
// 程序代码
}
finally中的代码总是会执行吗?
答案是 no, 一下两种情况是不会执行的
如果一个方法内在执行try{}语句之前就已经return了,那么finally语句指定不会执行了。因为它根本没有进入try语句中
如果在一个try语句中调用System.exit(0);方法,那么就会退出当前java虚拟机,那么finally也就没有执行的机会了。
finally在return之前执行还是在return之后执行?
看一下代码,来分析
public class TestFinally {
public static void main(String[] args) {
// System.out.println(method());//4. 所以,结果时 1
System.out.println(method2());//5. 所以,结果时 2
}
public static int method() {
int x = 1;
try {
return x;
//1. 当程序执行到这里时,就会先返回相应的值,
// 并把相应的值存储在一个临时栈中去保存这个结果 x= 1; 但并不会立即返回值
//3. 执行完finally语句后,会告诉主调程序,被调程序已经执行完了并把临时栈中的值返回,
} catch (Exception e) {
return 0;
} finally {
++x; //2. 然后来执行finally语句 ,x = 2
}
}
public static int method2() {
int x = 1;
try {
return x;
//1. 当程序执行到这里时,就会先返回相应的值,
// 并把相应的值存储在一个临时栈中去保存这个结果 x= 1; 但并不会立即返回
} catch (Exception e) {
e.printStackTrace();
return 0;
} finally {
++x; //2. 然后来执行finally语句 ,x = 2
return x; //3. 把x值存储在一个临时栈中,覆盖原来临时栈中的值x=1
}
//4. 执行完finally语句后,会告诉主调程序,被调程序已经执行完了并把临时栈中的值返回,
}
}
六、声明自定义异常
在Java中你可以自定义异常。编写自己的异常类时需要记住下面的几点。
所有异常都必须是Throwable的子类。
可以直接以Exception为父类
七、优缺点
优点:异常处理机制是代码的阅读,编写和调试工作更方便。
缺点:异常丢失