异常简单来说就是程序运行时出现了不正常的情况,有些我们可以处理,有些我们难以处理。
当出现Error时,一般是发生了非常严重的错误,由运行环境来处理;而对于Exception,我们可以对它进行处理,并且对于不同的Exception我们可以有不同的处理方式。
对于Exception,可以简单分为两类,运行时异常和编译时异常(也叫非运行时异常/检查时异常)
运行时异常:意味着程序存在bug,需要我们修改程序来避免这类异常,例如:数组越界、空指针异常等等。
编译时异常:当我们在写代码的时候就会提示出的异常,这类异常需要我们进行处理,就像“未雨绸缪”,它不一定会发生异常,但是我们预料它发生异常后的情况并进行了处理。
除了Java中已经定义好的一些异常,我们也可以自定义异常
当我们自定义的异常继承了Exception类时,它是一个编译时异常,当自定义异常继承了RuntimeException类时,它是一个运行时异常。通常我们在编写代码时,用的更多的是编译时异常。
对于编译时异常的处理
1、使用try catch 语句捕获异常(相当于自己处理了异常):
try {
// 需要检查的代码(可能会抛出异常,也可能不会抛出异常)
} catch(异常的类型 异常类型的变量) {
// 捕获异常后要处理异常
} finally {
// 一定会被执行的代码(不管异常抛不抛出都会执行)
}
2、通过throws语句抛出异常(相当于让调用方去处理异常)
使用多个catch语句来实现多重捕获块
try {
// 需要检测的代码(可能会抛出异常,也可能不会抛出异常)
} catch (异常的类型1 异常类型的变量1) {
// 捕获异常后处理异常
} catch (异常的类型2 异常类型的变量2) {
// 捕获异常后处理异常
} catch (异常的类型3 异常类型的变量3) {
// 捕获异常后处理异常
} finally {
// 一定会被执行的代码(不管异常抛不抛出都会执行,例如数据库释放连接)
}
注意:当try语句块中可能发生多种类型的异常时,要让子类异常在前,父类异常在后,否则程序会报错,因为子类类型的异常也会被前面父类变量的catch语句所捕获。但是不建议省去子类异常,因为一般会根据不同的异常会作不同的处理。