炎炎夏日,激情似火,又是一年毕业季,面对如此内卷的就业形势,哪能不卷一波,下面一起学习一下java基础之异常使用的姿势。 在java中,程序运行时可能会遇到特殊的情况,导致程序出错,将这些 “特殊情况” 称之为为java异常体系。异常是一种例外,程序在执行期间发生的事件,它中断正在执行程序的正常指令流。在开发过程中,很多情况都会导致异常的发生,如分母为负数,数组下标越界等。 在java中,一切皆为对象,所以异常也是对象,其异常层次如下 其顶级父类为Object类,异常分为两类:Error(错误)和Exception(异常),都继承自Throwable类,Error是程序猿无法处理的问题,Exception是程序猿可以处理的问题。Exception又分为两类:受检异常和非受检异常(运行时异常)。 受检异常是那种强制要求程序猿在代码中处理的异常,如果不处理,则代码无法编译。非受检异常是那种不要求程序猿必须处理,即使不处理,代码也能正常的编译通过。
- Error(错误):程序的内部错误或硬件问题,一般来说,出现了这种错误,程序就无法正常的运行下去,只能退出程序,程序员无法处理,如常见的内存溢出OutOfMemoryError;
- Exception(受检异常):编译时异常称为受检异常,Exception子类中除RuntimeException及其子类之外的异常,且受检异常必须手动在代码中添加捕获语句来处理该异常;
- RuntimeException(非受检异常或运行时异常):编译时不会报错,运行时才会报错,比如数组越界,空指针异常和类型转换异常,Java编译器会自动按照异常产生的原因引发相应类型的异常,程序中可以选择捕获处理也可以不处理;
异常的处理机制主要分为声明异常、抛出异常、捕获异常。
- 声明异常:throws,用在方法声明上,表示该方法可能会产生的异常类型,但是在本方法中不处理,由调用者进行处理;
// 使用throws声明异常
public void method() throws Exception{
// 方法体
}
上面方法通过throws声明了method可能抛出的Exception异常,需要这个方法的调用者来处理这个异常。
- 抛出异常:throw,用在方法内部,表示人为产生异常并抛出;
// 使用throws声明异常
public void method() throws Exception{
// 使用throw抛出异常
throw new Exception;
}
上面方法在异常被抛出后,需要被处理,java中异常的处理方式主要有两个,一是自己处理,二是向上抛,交给调用者处理。对于向上抛的方式,若是受检异常,则需要明确地再次声明异常,而非受检异常则不需要。
- 捕获异常:异常的处理方式要么向上抛,要么自己处理,但自己处理之前需要先捕获异常,然后才能处理。try{}语句块,里面写执行可能存在的异常的代码,catch捕获异常,finally无论是否发生异常,finally语句块中的代码总能执行;
// try ... catch ... finally
try {
// 代码块
} catch {
// 异常处理
} finally {
// 一定会执行的代码
}
上面的方法try和finally只能有一个,但catch可以有多个。
由上可见,自己明确知道如何处理的,就要处理,不知道如何处理的,就向上抛出,交给调用者处理。如果处理不了,请不要捕获异常。
捕获异常的顺序需要特殊注意,如可能抛出了很多个异常,所以会同时捕获了多个异常,如下
try {
} catch (Exception) {
} catch (MyException) {
} catch (IllegalArgumentException) {
}
上面的捕获方式最大的问题就是异常的捕获顺序不合理,因为后面的2个永远不会被捕获,异常一旦发生,直接被Exceptin异常捕获了,所以需要把范围较小的异常放到前面,如先RuntimeException、在Exception、最后Throwable。
在日常开发中会接触很多异常,jdk也内置了很多异常,这时也可以自定义一下业务异常,这些异常可以有一定的继承关系,方面快速识别异常的原因,如LoginFailedException。
SystemException extends RuntimeException{}
BusinessException extends RuntimeException{}
|