- 异常的概念:在Java中,将程序执行过程中发生的不正常行为称为异常(Exception)。
- 常见的异常(举例):
异常分很多种类,java中不同类型的异常,都有与其对应的类来进行描述。
- 算数异常(ArithmeticException)
System.out.println(10 / 0);
// 执行结果
Exception in thread "main" java.lang.ArithmeticException: / by zero - 数组越界异常(ArrayIndexOutOfBoundsExceptin)
int[] arr = {1, 2, 3}; System.out.println(arr[100]);
// 执行结果
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 100 - 空指针异常(NullPointerException)
int[] arr = null; System.out.println(arr.length);
// 执行结果
Exception in thread "main" java.lang.NullPointerException
- 异常的体系结构
Java内部维护了一个异常的体系结构,用于对不同异常或者错误进行很好的分类管理
由上图:
(后缀:Error——错误;Exception——异常)
- Throwable:是异常体系的顶层类,其派生出两个重要的子类, Error 和 Exception
- Error:指的是Java虚拟机无法解决的严重问题,比如:JVM的内部错误、资源耗尽等,典型代表: StackOverflowError(栈溢出)和OutOfMemoryError(堆上的一个溢出),一旦发生回力乏术。
比如:死递归---->栈溢出
Error是程序内部的错误,必须由程序员自己解决 - Exception:异常产生后程序员可以通过代码进行处理,使程序继续执行。比如:感冒、发烧。我们平时所说 的异常就是Exception。
当程序出现异常之后,将不会再继续执行异常之后的代码。
- 异常的分类
根据异常发生的时机不同,分类:
- 编译时异常(受检查异常 Checked Exception)
程序编译时期发生
特点:
编译时期一定要处理,否则代码不能编译通过。
(语法错误:比如,忘记加分号,不能算作编译时异常)
处理方法:
必须对其进行捕获或声明,以便抛出
(类比学习:继承抽象类,要么重写且抽象方法,要么自己也标注abstract抽象) - 运行时异常(非受检查异常---->Unchecked Exception)
程序运行期间发生
RunTimeException以及其子类对应的异常,都称为运行时异常
比如:NullPointerException、 ArrayIndexOutOfBoundsException、ArithmeticException。
特点:
运行时才能被发现
注意:编译时出现的语法性错误,不能称之为异常。例如将 System.out.println 拼写错了, 写成了 system.out.println. 此时编译过程中就会出错, 这是 "编译期" 出错。而运行时指的是程序已经编译通过得到 class 文件了, 再由 JVM 执行过程中出现的错误.(复习Java的执行过程)
- 异常的处理
1. 防御式编程 2.异常的抛出
防御式编程:
代码中的错误 客观存在,不可避免。
需要在程序出现问题的时候及时通知程序员。
主要的方式
a.LBYL: Look Before You Leap. 在操作之前就做充分的检查. 即:事前防御型
缺陷:正常流程和错误处理流程代码混在一起, 代码整体显的比较混乱。
b.EAFP: It's Easier to Ask Forgiveness than Permission. "事后获取原谅比事前获取许可更容易". 也就是先操 作, 遇到问题再处理. 即:事后认错型
优势:正常流程和错误流程是分离开的, 程序员更关注正常流程,代码更清晰,容易理解代码 异常处理的核心思想就是 EAFP。
在Java中,异常处理主要的五个关键字:throw、try、catch、final、throws
异常的抛出:
在编写程序时,如果程序中出现错误,此时就需要将错误的信息告知给调用者,比如:参数检测。
在Java中,可以借助throw关键字,抛出一个指定的异常对象,将错误信息告知给调用者(throw这个关键字,一般用于抛出自定义的异常)。
具体语法:throw new XXXException("异常产生的原因");
(“new”----异常是类)
(这属于 手动抛出异常)
如何让程序抛出异常?
抛出异常的方式:
1.某段程序 触发 之后,JVM抛出(Java原生带的异常)
2.通过关键字 throw 抛出异常 手动抛出(自定义的异常)
【注意事项】
1. throw必须写在方法体内部
2. 抛出的对象必须是Exception 或者 Exception 的子类对象(即:抛出的一定是异常)
3. 如果抛出的是 RunTimeException 或者 RunTimeException 的子类,则可以不用处理,直接交给JVM来处理
4. 如果抛出的是编译时异常,用户必须处理,否则无法通过编译
5. 异常一旦抛出,其后的代码就不会执行
异常的获取:
(未完待续……)