基本概念
1. 所有的异常都是从Throwable继承而来的,是所有异常的共同祖先。
2. Throwable有两个子类,Error和Exception。
Error
Error是错误,通常包括以下两类:
- 编译期的所有错误
类定义错误、少分号、符号错误等等
- 虚拟机自身错误(如上图)
内存溢出(递归)
Error表示的是程序自身无法处理的异常
什么叫程序自身无法处理?
对比Exception,是可以try catch捕获的,而error不可以
Exception
Exception是程序可以处理的异常,通过try catch语句块可以将出现的异常捕获,然后进行相应的处理。
Exception通常分为Runtime Exception和IO Exception,而所有的error和Runtime Exception都是unchecked exception
也就是说error和runtime exception是不必检查的异常,这个检查是指编译期,比如:
- 数组越界
- 除数为0
- 类为定义
这些异常在编译期是检查不出来的,只有运行的时候才能出现。
而另一方面,IOException被称为checked Exception。
可以注意到每次我们在写文件流的代码时,编辑器都会提示出这里可能出现FileNotFoundException,这就是编译期可预测的异常。
异常的处理
1. try-catch
try{
//需要执行的代码
}catch(Exception e){
//需要处理的异常
}
这里注意用了向上转型的概念,所有的Runtime Exception都继承于Excepition,当输出的时候则由编译期判断出具体的类型
2. throw/throws
如果用try-catch对异常捕获处理,也可以用throw/throws关键字将异常抛给上层方法处理,throw用于在方法内抛出异常,而throws用于方法名后声明可能抛出的异常类型,如下:
import java.io.*;
public class className
{
public void deposit(double amount) throws RemoteException
{
// Method implementation
throw new RemoteException();
}
//Remainder of class definition
}
3. finally关键字
finally 关键字用来创建在 try 代码块后面执行的代码块。
无论是否发生异常,finally 代码块中的代码总会被执行。
try{
// 程序代码
}catch(异常类型1 异常的变量名1){
// 程序代码
}catch(异常类型2 异常的变量名2){
// 程序代码
}finally{
// 程序代码
}
finally和return 的执行顺序
考虑到try-catch中的return,finally的执行发生在return执行之后返回之前,也就是说先执行return 后面的指令,再执行return。可以用debug试出来,如上图。