1. 异常
1.1 什么是异常
什么是异常:不正常的情况。
在Java中,异常是扰乱程序正常流的事件。它是一个在运行时抛出的对象。
1.2 为什么要处理异常
为什么要进行异常处理:异常通常会破坏应用程序的正常流程,异常处理可以保持应用的正常流程,这是异常处理的核心优势。
2. 异常的继承层次
2.1 异常分类
在Java中,异常对象都是Throwable类的子类。
Throwable分为Error和Exception。
Error类层次结构描述了Java运行时系统的内部错误和资源耗尽错误。
应用程序不应该抛出这种类型的错误,当发生Error时,程序应该被中断。
常见的Error包括 OutOfMemoryError, VirtualMachineError, AssertionError。
Exception层次结构又分为两种:一是派生自RuntimeException;二是其他异常类。
两者的划分标准是:由编程错误导致的异常属于RuntimeExpection;如果程序本身没有问题,但由于像I/O错误这类问题导致的异常属于其他异常。
常见的运行时异常包括:ArithmeticException, NullPointerException, ArrayIndexOutOfBoundsException等。
其他异常包括:IOException, SQLException等。
Java语言将继承自Error类或RuntimeException类的所有异常都被称为非受检异常,所有其他的异常称为受检异常。
对于非受检异常,编译器在编译时不会被检查,但是会在运行时进行检查,程序应该尽量避免非受检异常。
对于受检异常,编译器在编译时会检查是否为所有受检异常提供了异常处理器。
2.2 checked Exception 受检异常
除了Error和RuntimeException之外的所有异常都被称为受检异常,比如等。
程序编译会检查checked exception。
checked exception需要在代码中明确检查和处理。
2.3 非受检异常
3. Java 异常关键字
try:指定要防止异常代码的block。try不能单独使用,必须和catch和finally一起使用。
catch:用于处理异常的代码块。必须放在try后面,catch后面可以跟着finally代码块。
finally:用于执行程序的必要代码块,通常用于释放资源。不管有没有发生异常finally代码块都会执行。
throw:用于抛出一个异常,通常用在catch代码块中。
throws:用于声明异常,方法签名的一部分,指定方法中可能会发生的异常。
4. 处理异常的一些指导原则
4.1 异常的选择
- 只在异常的情况下才使用异常。
- 对于可恢复的情况,抛出受检异常;对于程序错误,抛出运行时异常。不确定是否可恢复,抛出未受检异常。
如何决定使用受检异常or运行时异常?如果期望调用者能够适当地恢复,就应该使用受检异常。通过抛出受检异常,强迫调用者在一个catch子句中处理该异常,或者将该异常传播下去。
运行时异常表示编程错误,所以自定义的所有非受检异常都应该是RuntimeException的子类。
优先选择系统提供的异常 | 异常 | 使用场合 | | —- | —- | | IllegalArgumentException | 非null的参数值不正确 | | IllegalStateException | 不适合方法调用的对象状态 | | NullPointerException | 在禁止使用null的情况下参数值为null | | IndexOutOfBoundException | 下标参数值越界 | | ConcurrentModificationException | 在禁止并发修改的情况下,检测到对象的并发修改 | | UnsupportedOperationException | 对象不支持用户请求的方法 |
更高层的实现应该捕获低层的异常,同时抛出更高层的异常