14、异常
一、异常(Exception)
Java在执行过程中可能会发生不正常的情况,这种非语法和逻辑上的错误,被称为异常。当程序抛出异常,程序就会崩溃,一个不太致命的问题到窒息系统崩溃,程序的健壮性太低,Java提供了异常处理机制来解决该问题,从而保证程序健壮性
1、什么是异常?
在程序中,错误可能产生于程序员没有预料到的各种情况。或者超出了程序员的可控范围的环境因素,如用户的坏数据,试图打开一个不存在的文件夹等,在Java中这种在程序运行时可能出现的一些错误称为异常。异常是一个在程序期间发生的事件,它中断了正在执行的程序的正常指令流,导致程序崩溃
Java类库的每个包都定义了异常类,所有的这些异常类都是Throwable
的子类。Throwable
类派生了两个类,分别是Error
类和Exception
类
(1)Error
(错误):及其子类用来描述Java运行系统中的内部错误以及资源耗尽的错误,JVM虚拟机无法解决的严重问题,道中程序崩溃
(2)Exception
(异常):称为异常,我为非致命性类,可以通过捕捉处理使程序继续执行
异常又分为两大类
- 运行时异常:程序运行中产生的异常,编译器检查不出来,是程序员应该避免出现的错误,可以不做处理,因为该类异常很普遍,全部处理可能会对程序的可读性和运行效率产生不利影响
- 编译时异常:javac编译时产生的异常,是编译器要求必须处理的异常
2、常见的运行时异常
异常 | 名称 | 意义 |
---|---|---|
NullPointerException | 空指针异常 | 当程序试图在需要对象的地方使用null时抛出该异常 |
ArithmeticException | 数学运算异常 | 当出现异常的运算条件时,抛出该异常 |
ArrayIndexOutOfBoundsException | 数组下标越界异常 | 数组下标超过数组长度 |
ClassCastException | 类型转换异常 | 当试图将指向子类对象的父类引用强制转换为非子类引用时 |
NumberFormatException | 数字格式异常 | 试图将字符串转换为一种数值类型,但该字符串不能转换为适当的格式时 |
3、常见的编译时异常
异常 | 意义 |
---|---|
SQLException | 操作数据库时,查询表可能发生异常 |
IOException | 操作文件,发生异常 |
FileNotFoundException | 操作一个不存在的文件时 |
ClassNotFoundException | 加载类,类不存在时 |
EOFException | 操作文件,到文件末尾,发生异常 |
ILLegalArguementException | 参数异常 |
4、怎么解决异常?
为了保证程序的有效执行,需要对发生的异常进行相应的处理。在Java中如果某个方法抛出异常,既可以在当前方法中捕捉,然后处理该异常,也可以将捕捉的异常向上抛出,交由方法调用者来处理
(1)try - catch - finally(异常捕获结构)
try {
//可能有异常的程序代码块;
} catch (Exception e) {
//捕获到异常,系统将异常封装为Exception对象e,传递给catch
//得到异常后,程序员自行处理
//若没发生异常,catch代码块不执行
} finally {
//不管try代码块是否有异常,finally始终都要执行(通常将释放资源的代码放在finally)
}
注意事项
- 异常发生时,后面的代码块不会执行,直接进入catch代码块
- 异常不发生,顺序执行,不会进入catch块
- 不管是否异常,都执行finally代码块
- 可以有多个catch语句,捕获不同的异常(进行不同的业务处理),要求父类异常在后,子类异常在前(子类异常可被父类异常捕捉)
- 可用try - catch
- 可用try - finally,没有捕获器会崩溃,使用场景:无论异常与否,比执行某个业务逻辑
(2)throws(抛出)
将发生的异常抛出,教给方法调用者来处理,最顶级的处理者为JVM
throws (异常类型);
注意事项
- f2方法中发生异常时,有两个选择
- try - catch - finally
- throws
- JVM处理异常:输出异常信息,退出程序
- 异常发生,不确定如何处理,此时应显式地抛出异常,表示该方法将不对异常进行处理,交由该方法的调用者处理
- 在方法声明中用throws语句可以声明抛出
- 运行异常若没处理,默认方式为throws处理
- 子类重写父类时,对抛出异常的规定:为了使父类能够接收子类异常,子类重写的方法所抛出的异常要么和父类一致,要么为父类异常的子类
- throws关键字后可以是异常列表,即抛出多个异常
- 调用的方法抛出的编译时异常必须在本方法中显式地处理掉
5、自定义异常
当程序出现某些”错误“,但该错误信息并没有在Throwable子类中描述处理,此时只需继承Exception类即可以设计自定义的异常类,用于描述错误信息
(1)步骤
- 创建自定义异常类:继承Exception或RuntimeException
- 继承Exception:为编译异常
- 继承RuntimeException:为运行异常(一般继承RuntimeException,运行时可以默认处理,而不用显式地处理)
- 在方法中通过
throw
关键字抛出异常对象 - 在出现异常方法的调用者中捕获并处理异常
(2)throws和throw的区别
意义 | 位置 | 后面跟着的东西 | |
---|---|---|---|
throws | 异常的一种处理方式 | 方法声明处 | 异常类型 |
throw | 抛出用户自定义异常对象 | 方法体中 | 异常对象 |