通过异常处理错误

一、概念

异常:阻止当前方法或作用域继续执行的问题。
异常和普通问题的区别:普通问题是指,在当前环境下能得到足够的信息,总能处理这个错误。异常就不能继续下去了,因为在当前环境下无法获得必要的信息来解决问题。你所能做的就是从当前环境跳出,并且把问题提交给上一级环境,这就是抛出异常时所发生的事情。

当异常抛出时,首先将使用new在堆上创建异常对象。然后,当前的执行路径被终止,并且从当前环境中弹出对异常对象的引用。此时,异常处理机制接管程序,并开始寻找一个恰当的地方来继续执行程序。这个恰当的地方就是异常处理程序,它的任务是将程序从错误状态中恢复,以使程序能要么换一种方式运行,要么继续运行下去。

异常使得我们可以将每件事都当作一个事务来考虑,如果出了什么问题,我们只需要放弃整个计算。我们还可以将异常看作是一种内建的恢复系统,因为我们在程序中可以拥有各种不同的恢复点。如果程序某部分失败了,异常将恢复到程序中已知的稳定点上。

异常的恢复模型:异常处理程序的工作是修正错误,然后重新尝试调用出问题的方法。那么在遇见错误时就不能抛出异常,而是调用方法来修正该错误。或者,把try块放在while循环里,这样就可以不断地进入try块,直到得到满意的结果。

二、异常的分类

Throwable这个Java类被用来表示任何可以作为异常被抛出的类。Throwable对象可分为两种类型(指从Throwable继承得到的类型):Error用来表示编译时和系统错误;Exception是可以被抛出的基本类型。

  1. Error(错误)表示系统级的错误和程序不必处理的异常,是java运行环境中的内部错误或者硬件问题。比如:内存资源不足等。对于这种错误,程序基本无能为力,除了退出运行外别无选择,它是由Java虚拟机抛出的。
  2. Exception(违例)表示需要捕捉或者需要程序进行处理的异常,它处理的是因为程序设计的瑕疵而引起的问题或者在外的输入等引起的一般性问题,是程序必须处理的。
    Exception又分为运行时异常、受检查异常。
    运行时异常,表示无法让程序恢复的异常,导致的原因通常是因为执行了错误的操作,建议终止程序,因此,编译器不检查这些异常。它不必在异常说明中声明方法将RuntimeException类型的异常,也被称为“不受检查异常”。这种异常属于错误,将被自动捕获,不需要程序员亲自动手了。
    出现运行时异常后,系统会把异常一直往上层抛,一直遇到处理代码。如果没有处理块,到最上层,如果是多线程就由Thread.run()抛出,如果是单线程就被main()抛出。抛出之后,如果是线程,这个线程也就退出了。如果是主程序抛出的异常,那么这整个程序也就退出了。运行时异常是Exception的子类,也有一般异常的特点,是可以被Catch块处理的。只不过往往我们不对他处理罢了。也就是说,你如果不对运行时异常进行处理,那么出现运行时异常之后,要么是线程中止,要么是主程序终止。
    说明:只能在代码中忽略RuntimeException类型的异常,其他类型异常处理都是由编译器强制实施的。作为程序员,应该在代码中进行检查的错误。(比如ArrayIndexOutOfBoundsException,就要写代码中判断一下数组的大小了)。你会发现在这些情况下使用异常很有好处,它们能给调试带来便利。
    受检查异常,是表示程序可以处理的异常,也即表示程序可以修复(由程序自己接受异常并且做出处理), 所以称之为受检查异常。

三、异常的使用

  1. 在构造器中使用try-catch
public class InputFile {
        private BufferedReader in;
        public InputFile(String fname) throws Exception {
            try{
                in = new BufferedReader(new FileReader(fname));
            }catch(FileNotFoundException e){
                System.out.println("Coule not open" + fname);
                throw e;
            }catch(Exception e){
                try{
                    in.close();
                }catch(IOException e2){
                    System.out.println("in.close() unsuccessful");
                }
                throw e;
            }finally{
                //Don`t close it here!!!
            }
        }
        public String getLine(){
            String s;
            try{
                s = in.readLine();
            }catch(IOException e){
                throw new RuntimeException("readLine() failed");
            }
            return s;
        }
        public void dispose(){
            try {
                in.close();
                System.out.println("dispose() successful");
            } catch (IOException e) {
                throw new RuntimeException("in.close() failed");
            }
        }
    }

如果FileReader的构造器失败了,将抛出FileNotFoundException异常。对于这个异常,不需要关闭文件,因为这个文件还没有被打开。而其他任何捕获异常的catch子句必须关闭文件,因为此时文件已经打开了。这里的一个特殊情况,就是构造阶段可能会抛出异常,并且要求清理的类
这种通用的清理惯用法在构造器不抛出任何异常时也应该运用,其基本规则是:在创建需要清理的对象之后,立即进入一个tru-finally语句块。

异常使用指南:
1. 在恰当的级别处理问题;
2. 解决问题并且重新调用产生异常的方法;
3. 进行少许修补,然后绕过异常发生的地方继续执行;
4. 用别的数据进行计算,以代替方法预计会返回的值;
5. 把当前运行环境下能做的事情尽量做完,然后把相同的异常重抛到更高层;
6. 把当前运行环境下能做的事情尽量做完,然后把不同的异常抛到更高层;
7. 终止程序;
8. 进行简化;
9. 让类库和程序更安全;
10. 异常使得你可以在运行时报告错误并从错误中恢复,但“报告”功能才是异常的精髓所在。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值