java编程思想笔记12-通过异常处理错误



java的基本理念是"结构不佳的代码不能运行".


12.1 概念
程序在编译时期和运行时期会发生的错误.
12.1 基本异常
当抛出异常后,有几件事情会随之发生.首先,通java中其他创建对象的创建一样,将使用new在堆伤创建异常对象.然后,当前的执行路径(它不能继续下去了)被终止,并且从当前环境弹出对异常的引用.此时异常处理机制接管程序,并开始寻找一个恰当的地方来继续执行程序.这个恰当的地方就是异常处理程序,它的任务是将程序从错误状态中恢复,以使程序能要么换一种方式运行,要么继续运行下去.
12.2.1 异常参数
所有的标准异常类都有两个构造器:一个是默认构造器;另一个是接收字符串错误参数,以便把相关信息放入异常对象的构造器.
12.3 捕获异常
try---catch
异常处理理论伤有两种基恩模型,java支持终止模型,在这模型中,将假设错误非常关键,以至于程序无法返回到异常发生的地方继续执行.一旦异常被抛出,就表明错误无法挽回,也不能回来继续执行.

另一种就是是恢复模型,
比如 把try放入while循环里
12.4创建自定义异常
不必拘泥于java中已有的异常类型.它们都是java类库自己操作定义的异常类型,如果我们有需要,请大胆的定义自己所需要的异常类型.
12.4.1 异常与记录日志
12.5 异常说明
throws表明方法声明异常
12.6 捕获所有异常
可以只有一个异常处理程序来捕获所有类型的异常,通过exception可以做到
String getMessage();
String getLocalizedMessage();

void printStackTrace();
void printStackTrace(PrintStream);
void pirntStackTrace(java.io.PrintWriter);

12.6.1 栈轨迹
printStackTrace()方法所提供的信息可以通过getStackTrace()方法来直接访问,这个犯法将返回一个由栈轨迹中的元素所构成的数组,其中每一个元素都是栈的一帧.元素0是栈顶的元素,并且是调用序列中的最后一个方法调用.数组的最后一个元素和栈底是调用序列中的第一个方法调用.
12.6.2 重新抛出异常
重新抛出异常会把异常抛给上一级环境中的异常处理程序,同一个try块的后续catch字句被忽略.此外,异常对象的所有信息都得以支持,所以高一级环境中捕获此异常的处理程序可以从这个异常对象中得到所有信息.
12.6.3 异常链
有时,常常想要在捕获一个异常后抛出另一个异常,并且希望把原始异常的信息保存下来,者被称为异常链.
12.7 标准异常
throwable exception error ioexception  第三方类库也可能会定义自己的异常
12.7.1 特例:runtimeException
术语运行时异常的类型有很多,它们会自动被java虚拟机抛出,所以不必在异常中说明把它们列出来.这些异常都是从runtimeException中继承而来,所以既体现了继承的有点,使用起来也方便.
12.8 使用finally进行清理
finally总能执行
12.8.1 finally用来做什么
对于没有垃圾回收和析构函数自动调用机制的语言来说,finally非常重要.它使得程序员保证;无论try发生了什么,内存总能得到释放.但java有垃圾会后机制,所以内从释放不再是问题.而且java也没有析构函数可工调用.
使用场景:当要把内存之外的资源恢复到它们的出事状态时,就要使用finally子句.这种需要清理的资源包括:已经打开的文件或网络连接,在屏幕上面的图形,甚至可以是外部世界的某个开关.
12.8.2 在return中使用finally
try{
return;
}finally{
//...
}

在finally内部,从何处返回无关紧要.
12.8.3 缺憾:异常丢失
在使用try和finally时,如果try抛出异常,finlly也抛出异常,只会显示finally的异常.
12.9 异常的限制
当覆盖方法的时候,智能抛出在基类方法的异常说明里列出的那些异常.这个限制很有用,因为者意味着,当基类使用的代码应用到其派生类对象的时候,一样能工作(这是面向对象的基本概念),异常也不例外.
12.10 构造器
对于在构造阶段可能会抛出的异常,并要求清理的类,最安全的使用方式就是使用嵌套的try语句
public ContructException() {
        try {
            BufferedReader in = new BufferedReader(new FileReader("D:\\cnjnb-air\\cnjnb-air-api\\src\\xxx.text"));
            try {
                String a ;
                while ((a = in.readLine()) != null){
                    System.out.println(a);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }finally {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }


12.11 异常匹配
catch抓取的匹配
12.12 其他可选方法
异常处理系统就像一个活门,使你能放弃程序的正常执行序列.当"异常情景"发生的时候,正常的执行已变的不可能或者不重要了,这时就要用到这个"活门".异常代表了当前方法不能继续执行的情形.开发异常处理系统的原因是,如果为每个方法所有可能发生的错误都进行处理的话,任务就显得过于繁重了,程序员也不愿意这么做.
12.12.1 观点
java无谓的发明了"被检查的异常".
在很多观点中,当开发小程序的时候,这有显著的效果,但是当程序变大的时候,开发效率下降了,而代码质量只有微不足道的提高.甚至毫无提高.
过去,我曾鉴定的认为"被检查的异常"和强静态类型检查对开发健壮的程序是非常必要的,但是我看到的以及我使用一些动态(类型检查)语言的亲身经历告诉我,这些好处实际伤来于:
  • 不在于编译器是否会强制程序员去处理,而是要有一致的,使用异常报告错误的模型.
  • 不再与什么时候进行检查,而是一定要有类型检查.也就是说,必须强制程序使用正确的类型,至于这种强制施加于编译时还是运行时,那倒没有关系.

此外,减少编译时施加的约束能显著的提高程序员的编程效率.事实上,反射和泛型就是用来补偿静态类型检查所带来的过多限制.
12.13 异常指南
  1. 在恰当的级别处理问题
  2. 解决问题并且重新调用产生异常的方法.
  3. 进行少许修补,然后绕过异常发生的地方继续执行
  4. 用别的数据进行计算,以代理方法预计会返回的值
  5. 把当前运行环境能做的事情尽量做完,然后把相同的异常抛出更高层
  6. 把当前运行环境能做的事情尽量昨晚,然后把不同的异常抛到更高层
  7. 终止程序
  8. 进行简化(如果你的异常模式使问题变得太复杂,那用起来会非常痛苦也很恼人)
  9. 让类库和程序更安全
12.14 总结
异常处理的优点之一就是它使得你可以集中精力解决你要解决的问题,而在另一处处理你编写的这段代码的错误问题.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值