当前课程知识点:“做中学”Java程序设计 > 第5章捕获并处理异常 > 5.2捕获异常 > Video
前面呢我们介绍了Java的异常处理机制
那么今天我们一起来看看
如何使用Java来处理这些异常
对一个已经抛出的异常对象
通常呢我们可以有三种方式对它进行处理
第1种方式呢我们可以通过try catch语法
对异常对象的进行捕获
并针对性的对它进行处理
第2种方式呢
并针对性的对它进行处理
第2种方式呢
我们可以用try catch语法对异常对象进行
捕获和处理以后呢
通过throws语句
将这个对象的 再次的抛出
交给它的上一级的调用者
继续进行处理
第3种方式呢如果你觉得当前的方法并不适合处理我们的异常对象
你还可以
通过方法的声明语句将这个异常对象交给我们 方法调用者让它来进行处理
那么接下去我们先来看看第一种
通过try catch语句
来捕获异常对象的方法
首先我们需要了解一下
try catch的语法这里try语句块用来包裹可能抛出异常的相关代码
虚拟机会尝试的 执行我们的try语句块的程序代码
如果在执行期间发生了异常
那么执行的流程
将会跳离我们异常发生点
然后依次比较
catch语句块当中声明的类型
如果抛出的异常对象的类型
恰好是我们catch当中描述的类型
或者是它的子类 那么
将会执行我们catch语句块的相关代码
为了理解这段话
我们对前面的除法的代码示例
使用try catch语法
对异常对象的进行捕捉
前面我们已经分析到
代码的第28行
将产生一个Arithmetic Exception的异常对象
那么我们就用try语句块包裹 这段可能产生异常的代码
这里的我再教大家一个技巧
选中这个代码行以后
单击鼠标的右键
选择surround with菜单当中的
try catch block这个菜单下
eclipse将自动的在选定语句的前后
加上我们的try catch语法框架
注意到在32行
对捕获的异常对象做了一个默认的打印
堆栈跟踪信息的一个处理
需要注意的是
当前的光标位置停留的地方
这里是用来
填写你要捕捉的异常类型的
默认的这里填了一个exception
根据异常类型的继承关系
Exception是所有异常的处理的父类
根据里氏替换原则
这将捕获所有的异常类型对象
而这里我们只是针对一个Arithmetic Exception的类型
所以我们需要将它修改成
Arithmetic Exception
这样只有Arithmetic Exception对象在抛出的时候才会被捕获
从而这个开始块才会得到运行
修改好我们的异常类型以后我们在catch代码当中用一个
输出语句来提醒用户呢
检查它的除数是否为0
好了
我们接下去测试一下我们的程序
我们将除数故意的输入为0
可以看到
catch块当中的
提示语句已经被正确的执行出来了
由此可见
我们异常对象已经被成功的捕获了
需要特别注意的是
任何派生于Runtime Exception 子类
通常都是那些
事先无法预测错误是否发生的一个执行期的异常
对这样的异常对象
编译程序并不强迫要求你对它进行处理
所以我们也称之为
非检查的异常
与之相对应的是
另一类的异常
他不继承于Runtime Exception
而是直接继承exception
这里的异常让我们称之为检查性的异常
对于检查性的异常
你必须要对他进行相应的处理
在演示我们的检查异常之前我们先来了解一下
throws是Java的一个关键字
它的作用是将异常对象的
抛出给方法的调用者
在方法的签名部分加上throws
表示这个方法在执行过程当中可能抛出某种类型的异常
如果你有多个异常类型用逗号
将它们分割
对于检查的异常我们必须对它进行处理
处理的方式那要么是通过我们的try catch 语句块会进行捕获
要么呢 可以通过
添加throws方法声明
将我们的异常对象抛出给方法的调用者由它来进行处理
如果你什么都不做
将导致我们编译失败
下面我们来看一个代码片段
进一步的认识和了解检查异常的情况
在这段代码当中
我们使用FileReader对象来打开放置在C盘的test.txt文件
请大家注意观察
new FileReader这个构造方法
在构造读文件对象的时候可能会抛出一个叫做
FileNotFoundException的异常类型对象
这对象是间接的继承于Exception
而不是RuntimeException的子类 根据我们前面的分析
他是一个检查异常 必须对它进行处理
要么使用try catch语句块对它进行捕获
要添加我们的方法签名
让它交给我们的方法调用者来处理
这里的波浪线告诉你
如果你不加处理
将无法编译通过
这一点
跟我们继承于RuntimeException的非检查异常是完全不同的
通过前面学过的方法
我们可以使用快捷方式为new FileReader构造方法添加一个try catch语句块
这个错误改好了
那么我们发现在读取文件的这个过程当中
bufferedReader.readline方法
同样会抛出一个
名字叫做IOException的异常
这个异常
也是一个检查的异常
我们必须对它进行处理
在这里来我们同样用try catch语句块
对这个readLine方法进行捕捉和处理
像这样我们连续添加了两个try catch语句块
让整个代码看起来有点复杂
事实上
我们没有必要为每一个抛出异常的语句单独的去使用一个try catch语句块
我们完全可以将
这些会抛出异常的语句块
放置到同一个try语句块当中
通过添加多个catch语句块来捕捉不同的异常对象
并对它们进行分别的处理
像的方式我们称为多重捕获
Multi catch
你看像这样代码是不是比刚才要简洁了许多
如果你不想在异常产生的read file方法当中处理异常对象
你还可以通过方法签名
将它继续的抛出给方法的调用者来处理
比如
像这样我们在readFile后面加上我们的throws标签
告诉我们
这个方法将抛出一个FileNotFoundException和IOException
多个异常类型之间需要用逗号进行分割那么
作为方法的调用者
main必须要对这个
方法的进行异常的处理
当然你也可以有两种方式
一种用try catch直接捕获对它进行处理
另外一种
继续的抛出交给我们的虚拟机去处理
除了自己处理之外
这里呢我们再演示一下如何再将他抛出的方法
这时候那就要用到
throw语法
需要特别注意的是
throw是Java的一个关键字
他后面紧跟的是一个抛出的异常类型的对象
和我们的throws标记完全不同
throws它是方法签名的一部分
用来标记可能抛出的异常类型
而我们的throw呢
它是一个具体的抛出动作和行为
由于在这个指定的路径当中
确实找不到我们所谓的C盘的test.txt文件
所以在虚拟机执行的过程当中
他将会打印出文件找不到的信息
随后呢
继续抛出给我们的虚拟机
虚拟机的默认处理就是把我们的
异常对象的堆栈信息给打印出来了
所以我们看到两个信息呢
都会出现
下面我们再来做一个实验
这次呢我们在
两个catch之前
再添加一个catch Exception的语句块
这时候你将看到这样一个
编译错误信息
Unreachable catch block for FileNotFound exception
it Is already handled by the catch block for exception
出现这样的编译错误时
是因为FileNotFound是exception的子类
如果将exception作为我们第一个catch语句块
在代码执行过程当中
按照里氏替换原则
所有的exception子类都符合我们的exception的条件
只有第一个语句块会得到处理
而后面的catch语句块
根本就没有机会得到执行
这也就提醒我们在设计多重catch的时候需要特别注意
不同类型的catch
他们的之间的顺序
越是通用的父类 我们就应该越放在后面
如果你的程序打开了
指定的文件以后
在读取这个文件的过程当中
抛出了异常
那么这些打开的文件如何被关闭呢
如果一个打开的文件没有及时得到关闭的话
那么
你就无法对它进行删除移动等其他的操作了
系统当中的很多重要资源
都需要考虑在异常发生时如何及时释放的问题
try catch语句框架为我们提供了资源管理的一个
finally语句块
这语句块的作用正如它的名字finally
不管程序有没有抛出异常
最终都将执行一遍finally语句块
所以我们可以将释放资源的工作放在这个语句块里面
来看下这个代码片段
在finally语句块当中
如果我们的SC对象是一个非空的对象
我们就将它执行close关闭操作
一旦执行过程当中抛出了文件找不到的异常
这个程序同样在异常处理完以后
会执行我们的finally语句块
甚至我们可以做一个实验来看一下
更极端一点
catch一进来以后
我们强制的用一个return语句
让整个方法返回 看看我们这个finally语句块
会不会得到执行
来运行下我们可以看到
这个finally语句块照样执行不误
做了这些实验以后我们可以总结一下
我们的异常分成两大类
那些直接或者间接的继承exception的
是检查性的异常
必须通过我们的程序代码对它进行处理
而那些直接或者间接的继承与runtime exception的呢
是非检查性的异常
我们可以可选的
对它进行处理
在处理异常的时候有三种方式
一种的是完全自己处理通过try catch语句会对它进行
捕捉处理
你也可以通过自己捕捉处理一部分以后
使用我们的throw语句
将这个异常对象进一步抛出交给
方法的上一级调用者对它进行处理对于检查性的异常
我们除了使用try catch语句块
还可以通过throws
关键字在方法的签名部分
添加检查异常的类型
从而让方法的调用者
对它进行处理异常都可以采用多重catch语法
在设计一个多重catch语法的时候
我们需要按照
由特殊到通用的原则
来对我们的异常类型进行排序
异常的捕获的可以添加一个
可选的finally语句块
这个语句块的作用
在不管有没有发生异常
都将会执行一次而且它总是保证在方法的返回之前会执行完
这个语句块
通常是我们执行
强制关闭资源的一个最佳场所
-1.1Java简介
--01Java简介
-1.2搭建Java开发环境
--Video
-1.3使用记事本编写Java程序
--Video
-1.4使用Eclipse开发Java程序
--Video
-1.5导入/导出Java项目
--Video
-1.6管理组织代码
--Video
-第1章初始Java--测试题
-2.1认识标识符
--Video
-2.2变量和变量类型
--Video
-2.3数据类型和类型转换
--Video
-2.4使用常量
--Video
-2.5使用注释
--Video
-2.6使用运算符进行算术运算
--Video
-第2章使用Java基本语法(1)--测试题
-2.7使用运算符进行逻辑处理
--Video
-2.8使用if进行流程控制
--Video
-2.9使用switch进行流程控制
-2.10使用循环
--Video
-2.11循环的跳出和继续
--Video
-2.12多重循环
--Video
-第2章使用Java基本语法(2)--测试题
-3.1认识类和对象
--Video
-3.2为类添加属性
--Video
-3.3为类添加方法
--Video
-3.4为类添加静态方法
--Video
-3.5递归方法
--递归方法
-3.6构造方法
--Video
-3.7重载方法
--Video
-第3章使用面向对象基础语法--测试题
-4.1使用继承语法
--Video
-4.2使用数组
--Video
-4.3使用数组类操作数组
--Video
-4.4使用抽象类
--Video
-4.5使用接口
--Video
-第4章使用面向对象高级语法--测试题
-5.1异常处理机制
--Video
-5.2捕获异常
--Video
-5.3创建自定义异常
--Video
-第5章捕获并处理异常--测试题
-6.1SWT图形界面
--Video
-6.2使用SWT布局管理-FillLayout
-6.3使用SWT布局管理-RowLayout
-6.4SWT中的事件模型
--Video
-6.5常见事件处理写法
--Video
-第6章使用SWT设计界面--测试题
-7.1微波炉模拟程序的界面制作
--Video
-7.2微波炉模拟程序的代码重构
--Video
-7.3微波炉模拟程序的事件监听
--Video
-7.4微波炉模拟程序的数字键盘
--Video
-7.6微波炉模拟程序CookTimer
--Video
-7.7微波炉模拟程序添加图像
--Video
-7.8微波炉模拟程序添加声音
--Video
-7.9微波炉模拟程序安装包制作
--Video