第6章:异常处理
1.异常概述
- Java程序的执行过程中如出现异常事件,可以生成一个异常类对象,该异常对象封装了异常事件的信息并将被提交给Java的运行时系统,这个过程称为抛出(throw)异常。
- 当Java运行时系统接收到异常对象时,会寻找能处理这一异常的代码并把当前异常对象交给其处理,这一过程称为捕获(catch)异常。
1.1 异常和错误
- Java语言中的异常事件分为两种:
- Exception是指那些程序中可能发生的、经过处理有可能恢复正常的非正常事件。经过处理后,可以不中断程序的执行。非致命的
- 如:输入输出异常(IOException)、运行时异常(RuntimeException)……
- Error是指那些程序中可能发生的、非常严重且无法恢复的非正常事件。将使程序中断执行而退出系统。 致命的
- 如: 虚拟机错误(VirtualMachineError )、内存溢出错误(LinkageError)……
- Runtime Exception是一类特殊的异常(Exception),如除0、数组下标超过范围等,其产生比较频繁,处理麻烦,如果显示的声明或捕获将会对程序的可读性和运行效率影响很大。因此可由系统自动检测并将它们交给缺省的异常处理程序,而用户可以不必对其进行处理。
- 如:算数异常(ArithmeticException)、索引越界异常(IndexOutOfBoundsException)……
- Exception是指那些程序中可能发生的、经过处理有可能恢复正常的非正常事件。经过处理后,可以不中断程序的执行。非致命的
1.2 标准异常类
1.3 不受检异常和和受检异常
2.异常处理方法
- 两种处理方法:
- 使用try-catch-finally语句块结构在程序代码中捕获和处理异常;
- 使用throws把异常对象通过层层向上抛出直至转交给JVM处理。Java语言称产生异常和转交异常的过程为抛出异常。(可以理解为甩锅)
2.1 捕获和处理异常
- 多个catch块时候,只会匹配其中一个异常类并执行catch块代码,而不会再执行别的catch块,并且匹配catch语句的顺序是由上到下
- 在catch中声明的异常对象catch(OneException e)封装了异常事件发生的信息,在catch语句块中可以使用这个对象的一些方法获取这些信息。
- getMessage() :获取错误性质
- toString() :给出异常的类型与性质
- printStackTrace() :指出异常的类型、性质、栈层次及出现在程序中的位置
- 通常在finally语句中可以进行资源的清除工作,如:关闭打开的文件、删除临时文件等
2.2 抛出异常
- throws和throw的区别:
- throws是在方法声明时放在方法头中的,作用是声明一个方法可能抛出的所有异常;
- throw则出现在方法体的内部,是一个具体的执行动作,作用是抛出一个具体异常对象。
例:在ThrowsException类中对于所有可能出现的异常并不catch,而只是在方法后加throws Exception来声明该方法中可能存在该类异常,让调用该方法的方法(如main方法)来处理
2.3 异常传递链
3.自定义异常
3.1 自定义异常的创建
3.2 自定义异常的抛出与捕获
定义异常类的代码写在程序中,与其他类定义并列成为程序的一部分,在使用时与已有的异常类基本相同,只是在throw子句中使用例如下面的语法:throw new MyException( );
异常处理综合示例
3:执行try中内容,此时throw2抛出了一个Exception异常,由于没有catch到RuntimeException,所以执行finally块中代码,然后返回到上一层
8:此时try块中代码执行完毕,并且此时有一个从里层抛出的Exception异常
9:catch到Exception异常,执行catch块中内容,可以看到getMessage只是给出了
总结
Java异常处理机制的优点
- 把各种不同的异常事件进行分类,体现了良好的层次性
- 处理异常的代码和“常规”代码分开,减少代码,增强可读性
- 使异常事件可以沿调用栈自动向上传播,而非通过函数返回值传播
- 可以统一或分别处理具有相同父类的异常
- 为具有动态运行特性的复杂程序提供了强有力的控制方式