第12章 通过异常处理错误 248
12.1 概念 249
12.2 基本异常 249
12.2.1 异常参数 250
12.3 捕获异常 250
12.3.1 try块 250
12.3.2 异常处理程序 250
12.4 创建自定义异常 251
12.4.1 异常与记录日志 253
12.5 异常说明 256
12.6 捕获所有异常 256
12.6.1 栈轨迹 257
12.6.2 重新抛出异常 258
12.6.3 异常链 260
12.7 Java标准异常 263
Throwable
—Error
—Exception
——RuntimeException
——非RuntimeException
12.7.1 特例:RuntimeException 263
12.8 使用finally进行清理 264
12.8.1 finally用来做什么 265
12.8.2 在return中使用finally 267
12.8.3 缺憾:异常丢失 268
某些情况下,使用finally会使异常丢失:前一个异常还没处理就抛出另一个异常
12.9 异常的限制 269
继承上的限制
12.10 构造器 271
在创建需要清理的对象之后,立即进入一个try—finally块
12.11 异常匹配 275
子类异常可匹配父类异常
12.12 其他可选方式 276
源于异常的来源以及其他处理方式,重点在于理解
12.12.1 历史 277
12.12.2 观点 278
12.12.3 把异常传递给控制台 279
12.12.4 把“被检查的异常”转换为“不受检查的异常” 279
12.13 异常使用指南 281
12.14 总结 281
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
| (1)程序出现的不正常的情况。 1、编译时异常:语法错误 2、运行时异常:逻辑错误(数组下标越界) (2)异常的体系 Throwable |--Error 严重问题,我们不处理,比如说内存溢出。 |--Exception |--RuntimeException 运行期异常,这种问题我们也不处理,因为是你的问题,而且这个问题出现肯定是我们的代码不够严谨,需要修正代码的。 |--非RuntimeException 编译期异常,必须处理的,否则程序编译不通过 (3)异常的处理: A:JVM的默认处理 把异常的名称,原因,位置等信息输出在控制台,同时会结束程序。 B:自己处理 a:try...catch...finally 自己编写处理代码,后面的程序可以继续执行 b:throws 把自己处理不了的,在方法上声明,告诉调用者,这里有问题,这个格式必须跟在方法的括号后面。
try...catch...finally的处理格式: try { 可能出现问题的代码; }catch(异常名 变量) { 针对问题的处理; }finally { 释放资源; } (4)面试题 A:编译期异常和运行期异常的区别? 编译期异常 必须要处理的,否则编译不通过 运行期异常 可以不处理,也可以处理 B:throw和throws是的区别 throws 用在方法声明后面,跟的是异常类名 可以跟多个异常类名,用逗号隔开 表示抛出异常,由该方法的调用者来处理 throws表示出现异常的一种可能性,并不一定会发生这些异常 throw 用在方法体内,跟的是异常对象名 只能抛出一个异常对象名 表示抛出异常,由方法体内的语句处理 throw则是抛出了异常,执行throw则一定抛出了某种异常 (5)finally关键字及其面试题 A:finally用于释放资源,它的代码永远会执行。特殊情况:在执行到finally之前jvm退出了 B:面试题 a:final,finally,finalize的区别? final:最终的意思,可以修饰类,成员变量,成员方法 修饰类,类不能被继承 修饰变量,变量是常量 修饰方法,方法不能被重写 finally:是异常处理的一部分,用于释放资源。 一般来说,代码肯定会执行,特殊情况:在执行到finally之前jvm退出了 finalize:是Object类的一个方法,用于垃圾回收
b:如果在catch里面有return,请问finally还执行吗?如果执行,在return前还是后?
会,前。实际上在中间。
C:异常处理的变形 try...catch...finally try...catch... try...catch...catch... try...catch...catch...fianlly try...finally 这种做法的目前是为了释放资源。
注意: A:try里面的代码越少越好 B:catch里面必须有内容,哪怕是给出一个简单的提示
注意事项: 1:能明确的尽量明确,不要用大的来处理。 2:平级关系的异常谁前谁后无所谓,如果出现了子父关系,父必须在后面。 注意: 一旦try里面出了问题,就会在这里把问题给抛出去,然后和catch里面的问题进行匹配, 一旦有匹配的,就执行catch里面的处理,然后结束了try...catch继续执行后面的语句。 d.JDK7出现了一个新的异常处理方案: try{ }catch(异常名1 | 异常名2 | ... 变量 ) { ... } 注意:这个方法虽然简洁,但是也不够好。 A:处理方式是一致的。(实际开发中,好多时候可能就是针对同类型的问题,给出同一个处理) B:多个异常间必须是平级关系。 (6)自定义异常 继承自Exception或者RuntimeException,只需要提供无参构造和一个带参构造即可
自定义异常: 1、定义一个类继承Exception类 2、定义一个带参数的构造方法 3、调用父类带参数的构造方法 public class MyException extends Exception { public MyException() { }
public MyException(String message) { super(message); } } (7)异常的注意实现 A:父的方法有异常抛出,子的重写方法在抛出异常的时候必须要小于等于父的异常 B:父的方法没有异常抛出,子的重写方法不能有异常抛出 C:父的方法抛出多个异常,子的重写方法必须比父少或者小
异常注意事项: A:子类重写父类方法时,子类的方法必须抛出相同的异常或父类异常的子类。(父亲坏了,儿子不能比父亲更坏) B:如果父类抛出了多个异常,子类重写父类时,只能抛出相同的异常或者是他的子集,子类不能抛出父类没有的异常 C:如果被重写的方法没有异常抛出,那么子类的方法绝对不可以抛出异常,如果子类方法内有异常发生,那么子类只 能try,不能throws
(8)异常中要了解的几个方法: public String getMessage():异常的消息字符串 public String toString():返回异常的简单信息描述此对象的类的 name(全路径名) ": "(冒号和一个空格) 调用此对象getLocalizedMessage()方法的结果 (默认返回的是getMessage()的内容) printStackTrace() 获取异常类名和异常信息,以及异常出现在程序中的位置。返回值void。 把信息输出在控制台。
Exception类中的方法: getMessage():获得异常相关的描述信息(获得异常产生的原因) printStackTrace():获得异常相关的描述信息(包括异常产生的 原因以及异常产生的位置)
|
书籍相关资源:
pdf文档链接:https://pan.baidu.com/s/1yuWb_kI0sB3yHLBndPcyEg 提取码:scvw
书中demo: https://github.com/BruceEckel/TIJ4-code
Thinking in Java 4th英文版的课后习题答案: http://greggordon.org/java/tij4/solutions.htm