Java编程思想(十一) —— 通过异常处理错误(2)

前面一篇提到异常的基本概念和使用的原因,后面一截比较难,然后就分开写出来。

1)finally清理

对于一些代码,无论try有无抛出,都希望执行,为了这样可以在异常处理最后加上finally语句。印象最深的是与数据库打交道的时候,finally永远要记得回收Connection等等。

这样无论异常是否抛出,finally子句总能被执行。这样就不怕发生内存中的资源一直占用的情况,印象深刻的还有老师讲的,公司一个新来的忘记写finally语句,后面内存的东西越来越多,整个系统死掉了。

有一个特别的是,try中有return语句,还是会继续执行finally里的语句。

缺憾:异常丢失

class ImportantException extends Exception{
    public String toString(){
        return "import";
    }
}
class LightException extends Exception{
    public String toString(){
        return "light";
    }
}

public class LoseException {
    static void i() throws ImportantException{
        throw new ImportantException();
    }
    static void l() throws LightException{
        throw new LightException();
    }
    public static void main(String[] args) {
        try{
            try {
                i();
             }finally{
                l();}
        }catch (Exception e) {
            e.printStackTrace();
        }
    }
}

important的异常还是丢失了,虽然书上的作者早已希望未来的版本会修正这个问题,但是目前版本7还是没改善啊。

另外,finally子句只用return也会丢失异常。

2)构造器问题

这个问题比较复杂,看了好久,和之前处理的不一样。

书上的原话,构造器会把对象设置成安全的初始状态,但是会有别的动作,比如打开一个文件,这样的动作只有在对象使用完毕并且用户调用了特殊的清理方法之后才清理。

为什么说和以前不一样,以前确实是像作者所说,用finally最后处理就行了。但是,构造器在创建的时候就失败呢?

<span style="font-size:18px;">public class TestConstructor {
    private BufferedReader bf;
    public TestConstructor(String name) throws Exception{
        try {
            bf = new BufferedReader(new FileReader(name));
        } catch (FileNotFoundException e) {
            System.out.println("can not open!");
            //其实还没打开,不需要关闭
            throw e;
        } catch(Exception e){
            try{
                bf.close();
            }catch(IOException ie){
                System.out.println("close faild");
            }
        }finally{
            //不要在这里关闭
        }
    }

    public String getLine() {
        String s;
        try {
          s = bf.readLine();
        } catch(IOException e) {
            throw new RuntimeException("getLine failed!");
        }
        return s;
      }

    public void dispose(){
        try {
            bf.close();
            System.out.println("dispose successful");
        } catch (IOException e) {
            throw new RuntimeException("getLine failed!");
        }
    }
}</span>

io流,构造器传参之后能把FileReader和BufferedReader合在一起,看不懂的话可以提前翻一下io流的内容。FileNotFoundException,其实文件都找不到,我们是不用进行清理的,因为finally在每次构造器完成都执行一遍,不能把关闭的语句写在这里,为什么和以前把清理的代码写在finally中不同呢?

目的不同,在这里我们需要TestConstructor对象在整个生命周期都处于打开状态。而之前的那些我们希望的是快点用完快点关闭。

还有一个特别的地方,本来String是要初始化的,但是因为异常的抛出可以不用初始化。真正不用TestConstructor的时候,就调用dispose方法清除。

<span style="font-size:18px;">public class Clean {
    public static void main(String[] args) {
        try {
            TestConstructor tc = new TestConstructor("a.txt");
            try{
                String s ;
                int i ;
                while((s = tc.getLine())!=null){
                    //自己要进行的字符处理
                }
            }catch(Exception e){
                e.printStackTrace();
            }finally{
                tc.dispose();
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally{
            System.out.println("failed constructed!");
        }
    }
}</span>

这种嵌套是要自己去写的,Eclipse不给提示,因为语句已经在一个try块里面了。仔细分析一下,这个嵌套写的很漂亮,因为构造失败的话,我们根本就不需要去关闭TestConstructor,相反,构造成功的话,我们最后记得要清理,这和上面红字的地方是对应的,TestConstructor是读取文件的,我们确实需要再整个生命周期里面打开,而Clean这个类是调用Testconstructor这个类的,当成功构造和使用完读取字符串之后,自然而然就用dispose关闭,只不过我以前写程序的时候没有注意到,finally的处理和try,catch的嵌套可以写得这么美,真让人拍案叫绝。

3)异常匹配

这个问题比较简单,异常抛出后,找到匹配的处理程序后,就认为异常将的到处理,不再继续寻找。

try {
} catch (FileNotFoundException e) {
   System.out.println("can not open!");
} catch(Exception e){
}

如果异常与第一个匹配,那就捕获,如果不是,就由Exception捕获,因为Exception会捕获Exception以及其他从它派生的异常。

其他可选方式:

异常处理一个原则是“只有你知道如何处理才去捕获异常”,前面一篇文章已经说过,异常其实是为了将错误发生的地点的代码和处理错误的代码分开,让你专心写前者的代码。

作者自己也曾经犯过错误:

    try{
    }catch(Exception e){}

称为:harmful if swallowed,吞食有害,异常有,因为catch是必须加上的,但是有没有进行处理,就这样被吞了。所以,要么写好错误处理,要么抛给高层。

4)历史与观点

历史就不说了,书上太长了。

说一下一个CLU设计师的观点——我们觉得强迫程序员在不知道该采取什么错事的时候提供处理程序是不现实的。但是我们也知道,放在那里不理也是不现实的,这是我自己的话,所以异常是个好东西。

总结:异常让我们可以集中精力解决问题,就是问题和业务逻辑的代码分开后再集中处理。

摘抄一下书上的异常使用指南:

把当前运行环境能做的事情尽量做完,然后把不同或者相同的异常抛向更高层。

让类库和程序更安全。

作为程序设计不可分割的一部分,要学会使用。

时间: 2024-12-20 12:37:25

Java编程思想(十一) —— 通过异常处理错误(2)的相关文章

Java编程思想(九) —— 通过异常处理错误(1)

前阵子看到一个编程的学习方法--橡皮鸭调试法,就是拿一只小黄鸭. 面对面,跟他讲解你的编程思路,如果你没有橡皮鸭或者是一个能听你讲java,c,cpp,前端,io,系统内核,汇编,数据结构,计算机网络的女朋友,那么写博客也是你自己梳理好思路的一个好方法. 书中原话:java的基本理念是结构不佳的代码不能运行. 其实我之前也搞不懂为什么要弄个这样的东西出来,其实跟书上讲的一样,"异常"有"对此感到意外"的意思,问题出现了,我们不知道怎么处理,但又不能置之不理,可以停下

Java编程思想学习(九) 异常处理

java的异常处理机制可以使程序有极好的容错性,让程序更加的健壮.所谓的异常,就是指的阻止当前方法或作用域继续执行的问题,,当程序运行时出现异常时,系统就会自动生成一个Exception对象来通知程序.这样就极大的简化了我们的工作. 当然java的异常对象有很多种,下面这幅图显示了java异常类的继承体系.  从图片中可以看到java将所有的非正常情况分成了两种: 异常(Exception)和错误(Error),他们都继承Throwable父类.Error错误一般是指与虚拟机相关的问题,如系统崩

异常笔记--java编程思想

开一个新的系列,主要记一些琐碎的重要的知识点,把书读薄才是目的...特点: 代码少,概念多... 1. 基本概念 异常是在当前环境下无法获得必要的信息来解决这个问题,所以就需要从当前环境跳出,就是抛出异常.抛出异常后发生的几件事: 1.在堆上创建异常对象. 2.当前的执行路径中止                                          3. 当前环境抛出异常对象的引用.                                         4. 异常处理机制接

《Java编程思想(第4版)》pdf

下载地址:网盘下载 内容简介 编辑 本书赢得了全球程序员的广泛赞誉,即使是最晦涩的概念,在Bruce Eckel的文字亲和力和小而直接的编程示例面前也会化解于无形.从Java的基础语法到最高级特性(深入的面向对象概念.多线程.自动项目构建.单元测试和调试等),本书都能逐步指导你轻松掌握.[1] 从本书获得的各项大奖以及来自世界各地的读者评论中,不难看出这是一本经典之作.本书的作者拥有多年教学经验,对C.C++以及Java语言都有独到.深入的见解,以通俗易懂及小而直接的示例解释了一个个晦涩抽象的概

java编程思想总结(三)

java编程思想总结(三) java编程思想总结是一个持续更新的系列,是本人对自己多年工作中使用到java的一个经验性总结,也是温故而知新吧,因为很多基础的东西过了这么多年,平时工作中用不到也会遗忘掉,所以看看书,上上网,查查资料,也算是记录下自己的笔记吧,过一段时间之后再来看看也是蛮不错的,也希望能帮助到正在学习的人们,本系列将要总结一下几点: 面向对象的编程思想 java的基本语法 一些有趣的框架解析 实战项目的整体思路 代码的优化以及性能调优的几种方案 整体项目的规划和视角 其它遗漏的东西

java编程思想笔记(第一章)

Alan Kay 第一个定义了面向对象的语言 1.万物皆对象 2.程序是对象的集合,他们彼此通过发送消息来调用对方. 3.每个对象都拥有由其他对象所构成的存储 4.每个对象都拥有其类型(TYpe) 5.某一特定类型的所有对象都可以接收同样的消息. Booch提出一种更简洁的描述: 对象拥有状态(state) 行为(behavior) 和标识(identity) 每个对象都有一个接口 每个对象都属于定义了特性和行为的某个类(特性可以理解为属性的状态,行为可以理解为method) 在面向对象的程序设

《Java编程思想》读书笔记

前言 这个月一直没更新,就是一直在读这本<Java编程思想>,这本书可以在Java业界被传神的一本书,无论谁谈起这本书都说好,不管这个人是否真的读过这本书,都说啊,这本书很好.然后再看这边书的厚度,哇塞,厚的真的不止一点点,所以很多人看了没多久就放弃了,看不下去,但是基于它的厚度,就说,这是一本好书.也有人说,看了没什么用的一本书,甚至还去嘲笑那些正在看的人,说还不如看点实际的技术.那么在我的世界里,如果一本书没有读过,如果妄加评论的话,没有任何的意义.所以我真的仔仔细细读了下来,书上也写了很

Java编程思想(第4版)pdf高清版免费下载

下载地址:网盘下载 备用地址:网盘下载 内容简介编辑本书赢得了全球程序员的广泛赞誉,即使是最晦涩的概念,在Bruce Eckel的文字亲和力和小而直接的编程示例面前也会化解于无形.从Java的基础语法到最高级特性(深入的面向对象概念.多线程.自动项目构建.单元测试和调试等),本书都能逐步指导你轻松掌握.[1] 从本书获得的各项大奖以及来自世界各地的读者评论中,不难看出这是一本经典之作.本书的作者拥有多年教学经验,对C.C++以及Java语言都有独到.深入的见解,以通俗易懂及小而直接的示例解释了一

Java编程思想【Thinking in java】

Java编程思想[Thinking in java]目录:第1章 对象导论1.1抽象过程1.2每个对象都有一个接口1.3每个对象都提供服务1.4被隐藏的具体实现1.5复用具体实现1.6继承1.6.1“是一个”(is-a)与“像是一个”(is-like-a)关系1.7伴随多态的可互换对象1.8单根继承结构1.9容器1.9.1参数化类型(范型)1.10对象的创建和生命周期1.11异常处理:处理错误1.12并发编程1.13Java与Internet1.13.1Web是什么1.13.2客户端编程1.13