(PPT来源:廖雪峰老师网课)
异常
Java 将异常当作对象来处理,并定义一个基类 java.lang.Throwable
作为所有异常的超类。
- 异常分为两大类:
Error —— 发生了严重的错误,程序不能进行调整的
Exception —— 运行时出现的逻辑错误,需要捕获并处理
体系结构如下,其中红色为必须捕获的异常——CheckedException
- 异常可以在任何地方抛出
- 异常是class,本身带有类型信息
- 异常只需要在上层捕获,和方法调用分离
异常的体系
申明异常
利用 try{…} catch( ) {…} finally{…} 捕获异常:
- 可以使用多个catch语句,每个catch对应捕获,从上到下匹配,所以子类异常应写在前面,否则会被父类捕获
- finally语句 可有可无;总是最后执行;有无错误时都执行
- 如果几种异常不存在继承关系,可以在 catch 中用 | 一次编写多个
对可能抛出CheckedException的方法调用:
4. 捕获Exception并处理
5. 不捕获但通过throws申明(即放在上层去捕获)
6. main() 是最后捕获Exception的机会(仍未捕获,JVM就会报错退出)
- eg:
- 1
此时捕获异常,try后续的“ok”不再执行 - 2
没有进行异常捕获,编译器会提示编译错误,并给出处理方式(向上抛出异常)
可以在上层捕获或继续向上抛出异常
直至 main() 方法,如果还没有捕获,虚拟机就会关掉程序,打印出出错信息
- 小结
异常的传播
printStackTrace( ) 可以打印出方法的调用栈,对于调试错误很有用。可以跟踪找出异常是从哪个代码抛出的
![](https://i-blog.csdnimg.cn/blog_migrate/0abfc8be08e2f981b9feb1a0480dce33.png)
异常的转换
如果一个方法捕获了某个异常后,又在 catch 子句中抛出新的异常,就“转换”了异常,会导致原始异常丢失;
可以在新抛出的异常中添加原始的异常信息 e 来解决:
![](https://i-blog.csdnimg.cn/blog_migrate/f5274b9a49f791fb03d3b5837528b0b3.png)
![](https://i-blog.csdnimg.cn/blog_migrate/ffdbb36db35a926b48cf32185e41f149.png)
catch 如果将要抛出异常,则会先执行 finally 语句:
- finally 中正常打印完成,再返回 catch 异常
- 此时若 finally 语句中有异常,则会捕获 finall 中的异常,而使得原 catch 中的异常被屏蔽(Java只能传播一个异常,后抛出没有被 catch 的会被前面的覆盖屏蔽掉)
保存所有异常
- 用origin 变量保存原始异常
- 如果存在原始异常,用 addSuppressed() 添加新异常
- 如果存在原始异常 或 新异常,最后在 finally 之后抛出
![](https://i-blog.csdnimg.cn/blog_migrate/9934564e8ee8bbc1a49741a1d4541cf6.png)
- for 循环遍历,getSuppressed() 获取所有异常信息
![](https://i-blog.csdnimg.cn/blog_migrate/87a5a00cc2a72bbdacd3b928afaa0871.png)
- 小结
后续为Logging日志内容