文章目录
1.概念
-
发现错误的时机:运行程序之前(编译阶段)
-
异常:我对此感到意外
-
好处:能够降低处理错误代码的复杂度。
-
异常情形:阻止当前方法或作用域继续执行的问题
-
普通问题:当前有足够信息可以解决问题
-
异常情形:当前没有足够信息可以解决问题
-
抛出异常:从当前情形跳出,并把问题交给上一级
-
抛出异常后,做什么
- (1) 在堆上创建异常对象(new)
- (2) 终止当前执行路径,弹出异常对象引用
- (3) 异常处理机制接管程序
- 异常处理程序
- 将程序从错误状态中恢复,使程序换一种方式运行或继续运行下去
-
(1) 异常类有两种构造器:
i. 默认构造器
ii. 接受字符串(异常类型等信息)作为参数的构造器 -
(2) 异常对象传给throw(返回异常对象,退出方法或作用域)
-
(3) 异常类型根类:Throwable
3.捕获异常
- 监控区域:一段可能产生异常的代码,并且后面跟着处理这些异常的代码
- 如果在方法内部抛出异常,这个方法将在抛出这个异常过程中结束。如不希望方法结束,可以在方法中设置try()块捕获异常
- 异常处理程序
-
(1) 异常处理程序(catch()代码块)紧跟try块后
-
(2) 每个catch()语句只能接受一种类型的参数,且必须有标识符(类似方法参数)
-
(3) 异常查找过程
i. 异常抛出
ii. 异常处理机制搜索参数与异常类型匹配的第一个程序
iii. 执行catch
iv. catch结束(查找过程结束) -
(4) 异常处理的模型
i. 终止模型:假设错误无法挽回,终止执行
ii. 恢复模型(会导致耦合):希望异常被处理之后可以继续执行
a. 调用方法修正 b. 将try放入while循环直至满意
4.创建自定义异常
-
(1) 向Logger写入:直接调用与日志记录消息级别相关联的方法(server())
-
(2) 显示异常抛出栈轨迹:
StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); e.printStrackTrace(pw); logger.error(sw.toString());
5.异常说明
- Java提供了自顶向下强制执行的异常说明机制
- 异常说明属于方法说明的一部分,紧跟形势参数列表
- throws + 潜在异常类型列表
- 被检查异常:在定义抽象基类或接口时这种能力很重要,这样派生或接口实现就能抛出这些预先抛出的异常
6.捕获所有异常
- 捕获所有异常要放最后:
catch(Exception e){}
- (1) String getMessage()
- (2) String getLocalizedMessage()
- 返回对Throwable的简单描述(获取异常种类和错误信息)
- String toString()
- (1) void printStackTrace()输出到标准错误
- (2) void printStackTrace(PringStream)可选输出流
- (3) void printStackTrace(java.io.PringStream)可选输出流
- Throwable fillInStackTrace()
- getClass()
- getName()
- getSimpleName()
- getStackTrace()返回一个由栈轨迹元素构成的数组,其中每一个元素都表示栈中一帧
- (1) 当得到了当前异常的而对象引用e(catch Exception e),可以直接重新抛出异常(catch(Exception e){throw e;})
- (2) 重新抛给上级异常处理程序,同一个try块后所有catch语句被略
- (3) 调用fillInStackTrace()的那一行就成异常新发地了
按照方法调用的顺序入栈:main->f3->f2->f1
输出为
chapter12.CustomException3: chapter12.CustomException2: chapter12.CustomException1: custom
at chapter12.Test55.f3(Test55.java:24)
at chapter12.Test55.main(Test55.java:30)
Caused by: chapter12.CustomException2: chapter12.CustomException1: custom
at chapter12.Test55.f2(Test55.java:16)
at chapter12.Test55.f3(Test55.java:22)
... 1 more
Caused by: chapter12.CustomException1: custom
at chapter12.Test55.f1(Test55.java:9)
at chapter12.Test55.f2(Test55.java:14)
... 2 more
可以看出
(1)异常链上所有异常按照抛出的顺序逆序显示(和栈轨迹相反),最后一个抛出的为主异常,其他为原因。
(2)冒号后面是前一个异常原因msg的拼接。(如此保证第一个可以看到所有原因的msg)
由此可以看出异常链,可以称为 ”抛出异常“的链路。
- (1) 捕获一个异常后抛出另一个异常,并希望把原始异常的信息保存下来
- (2) 带有cause参数(表示原有异常)的构造器有:Error、Exception、RuntimeException。
- (3) 如果把其他类型的异常链关联起来用inCause()方法
7.Java标准异常
- (1) Error:编译时和系统错误
- (2) Exception:Java类库、用户方法以及运行时错误
- 异常基本概念
- 名称代表发生的原因
- (1) 运行时异常RuntimeException属于错误,将被自动捕获
- (2) 若RuntimeException没有被捕获而直达main(),那么程序退出前将调用异常的printStackTrace()方法
- (3) 在一个地方发生异常,往往在另一个地方导致错误
8.使用finally进行清理
- (1) finally能保证,无论try块里发生了什么,内存总能得到释放
- (2) 当要把除内存之外的资源恢复到他们初始状态,用finally子句
- (3) 当涉及break和countinue语句时,finally子句总会执行
- 在return中使用finally
- 在finally类内部,从何处返回无关紧要
- (1) 异常可能会丢失finally后面,外围catch()中更细微和难以察觉的异常
- (2) 从finally子句中return会丢失异常
9.异常的限制
- 子类抛出异常要小于父类
- 子类构造器可以抛出任何一场,但必须包含基类已经说明的异常
- 派生类构造器不能捕获(catch)基类构造器抛出的异常(super()要写在第一行,super()try{}catrch()不到)
- 通过强制派生类方法的异常说明,对象的可替换性得到了保障
- 不能基于异常说明来重载方法
10.构造器
- 在一个单独try-catch语句中构造对象,一旦对象构造成功(即构造函数未抛出异常)用另外的嵌套try-catch-finally语句写其他功能,在finally中记得清理该对象的资源。
11.异常匹配
- 异常处理系统按照代码顺序就近查找处理程序
- 派生类对象可以匹配基类处理程序
12.其他可选方式
- 异常处理系统让你放弃程序正常执行序列
- 目标:把错误代码同错误发生的地方相分离
- “被检查的异常”:吞食则有害
13.异常使用指南
- 在知道该如何处理的情况下才捕获异常
- 解决问题并且重新调用产生异常的方法
- 进行少许修补,然后绕过异常发生的地方继续执行
- 用别的数据进行计算,以代替方法预计会返回的值
- 把当前环境下能做的事情尽量做完,然后把相同的异常重抛到更高层
- 把当前环境下能做的事情尽量做完,然后把不同的异常抛到更高层
- 终止程序
- 进行简化
- 类库和程序更加安全