第十二章 通过异常处理错误

    科技2024-03-30  99

    文章目录

    1.概念抛出异常后,做什么异常参数 3.捕获异常4.创建自定义异常异常与记录日志 5.异常说明6.捕获所有异常获取错误信息打印调用栈轨迹记录栈帧的当前状态返回一个表示此对象类型的对象查询这个class对象包含包信息的名称只产生类名称栈轨迹重新抛出异常异常链 7.Java标准异常Throwable特例RuntimeException 8.使用finally进行清理finally用来做什么缺憾:丢失异常 9.异常的限制10.构造器11.异常匹配12.其他可选方式13.异常使用指南

    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.创建自定义异常

    要自定义异常类,必须继承已有异常类

    对于异常最重要的是类名

    调用Throwable中的printStackTrace()打印的是“从方法调用到异常抛出处”的方法调用序列

    异常与记录日志

    (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()
    查询这个class对象包含包信息的名称
    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标准异常

    Throwable这个Java类用来表示任何可以作为异常被抛出的类

    Throwable
    (1) Error:编译时和系统错误(2) Exception:Java类库、用户方法以及运行时错误 异常基本概念 名称代表发生的原因
    特例RuntimeException
    (1) 运行时异常RuntimeException属于错误,将被自动捕获(2) 若RuntimeException没有被捕获而直达main(),那么程序退出前将调用异常的printStackTrace()方法(3) 在一个地方发生异常,往往在另一个地方导致错误
    8.使用finally进行清理

    无论异常是否被抛出,finally子句总被抛出

    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.异常使用指南
    在知道该如何处理的情况下才捕获异常解决问题并且重新调用产生异常的方法进行少许修补,然后绕过异常发生的地方继续执行用别的数据进行计算,以代替方法预计会返回的值把当前环境下能做的事情尽量做完,然后把相同的异常重抛到更高层把当前环境下能做的事情尽量做完,然后把不同的异常抛到更高层终止程序进行简化类库和程序更加安全
    Processed: 0.019, SQL: 8