本讲内容:异常
软件开发中有80%的工作是用来检查和处理错误,而检查并处理错误很多时候是一件枯燥无趣的事情,如果在语言级别提供一些帮助的话,会减轻一些程序员的负担。
而Java提供了一套比较优秀的异常处理机制:
1、使开发人员不必编写特殊代码来测试返回值就能发现问题,
2、在语法结构就把正常的代码和异常处理的代码清晰的分开来,
3、允许我们使用相同的异常处理代码来处理一定范围内的所有异常。
以期产生一种高效的、有组织的异常处理方式。
1、异常及异常的分类
异常是指在程序中出现的异常状况,在Java中异常被抽象成一个叫做Throwable的类。
其中如果程序出错并不是由程序本身引起的,而是硬件等其他原因引起的,我们称之为Error,一般情况下Error一旦产生,对程序来说都是致命的错误,程序本身无能为力,所以我们可以不对Error作出任何处理和响应。
异常如果是由程序引起的我们称之为Exception,Exception又分两种,我们把运行时才会出现的异常叫做
RuntimeException,RuntimeException我们不好在程序编写阶段加以事先处理,而其他异常则可以在程序编写和编译阶段加以事
先检查和处理,我们把这种异常叫做检验异常。
程序只需要捕捉和处理检验异常。
相应的我们把除检验异常(可检查异常)之外的异常称之为非检验异常,包括Error和RuntimeException
,非检验异常可以捕捉也可以不捕捉,更多的时候我们不捕捉,因为捕捉了我们也没办法处理,譬如程序运行时发生了一个
VirtualMachineError异常,虚拟机都出错了,作为运行在虚拟机内的程序又有什么办法处理呢?
下面我们用图来表示一下上面讲述的内容:
2、异常的处理 try ^ catch ^ finally
异常相关的处理语法可以用下图概括一下:

异常处理的几条规则:
- try用于定义可能发生异常的代码段,这个代码块被称为监视区域,所有可能出现检验异常的代码写在这里。
- catch代码段紧跟在try代码段后面,中间不能有任何其他代码。
- try后面可以没catch代码段,这实际上是放弃了捕捉异常,把异常捕捉的任务交给调用栈的上一层代码。
- try后面可以有一个或者多个catch代码段,如果有多个catch代码段那么程序只会进入其中某一个catch。
- catch捕捉的多个异常之间有继承关系的话,要先捕捉子类后捕捉父类。
- finally代码段可以要也可以不要。
- 如果try代码段没有产生异常,那么finally代码段会被立即执行,如果产生了异常,那么finally代码段会在catch代码段执行完成后立即执行。
- 可以只有try和finally没有catch。
下面提供一个使用异常的例子,请注意看相关注释:
| 001 | import java.io.BufferedReader; |
| 002 | import java.io.BufferedWriter; |
| 003 | import java.io.FileNotFoundException; |
| 004 | import java.io.FileReader; |
| 005 | import java.io.FileWriter; |
| 006 | import java.io.IOException; |
| 007 | import java.util.ArrayList; |
| 008 | import java.util.List; |
| 013 | List list = new ArrayList(); |
| 017 | String[] account = { "10001", "aya", "111111", "60000" }; |
| 019 | account = new String[] { "10002", "bean", "222222", "40000" }; |
| 023 | //用BufferedWriter和BufferedReader读写文件 |
| 027 | // 字符串数组转字符串,试图写一个通用方法 |
| 028 | public static String arrayToString(String[] input, String space) { |
| 030 | for (int i = 0; i < input.length; i++) { |
| 031 | output += input[i] + space; |
| 033 | return output.substring(0, output.length() - 1); |
| 037 | public void writeFile() { |
| 039 | //try代码块又称之为"监视区域",表示有可能出问题闹异常的代码写在这里 |
| 040 | bw = new BufferedWriter(new FileWriter("bank.txt")); |
| 041 | for (String[] account : list) { |
| 042 | bw.write(arrayToString(account, " ")); |
| 046 | } catch (IOException e) { |
| 053 | //finally提供了一个在正常时和异常时都需要执行的代码段,在这里可以进行一些资源的释放工作,数据的清理工作 |
| 056 | } catch (IOException e) { |
| 064 | public void readFile() { |
| 066 | //try代码块又称之为"监视区域",表示有可能出问题闹异常的代码写在这里 |
| 067 | br = new BufferedReader(new FileReader("bank.txt")); |
| 070 | while ((temp = br.readLine()) != null) { |
| 071 | list.add(temp.split("")); |
| 073 | } catch (FileNotFoundException e) { |
| 079 | } catch (IOException e) { |
| 080 | //也可以用一组catch来捕捉多个异常,如果多个异常之间有继承关系,那么父类异常写下面 |
| 083 | //finally提供了一个在正常时和异常时都需要执行的代码段,在这里可以进行一些资源的释放工作,数据的清理工作 |
| 086 | } catch (IOException e) { |
| 092 | public static void main(String[] args) { |
| 094 | Bank02 bank = new Bank02(); |
3、常见异常
| ArrayIndexOfBound***ception |
数组下标越界异常 |
| ClassCastException |
强制转换类失败异常 |
| IllegalArgumentException |
方法参数类型传入异常 |
| IllegalStateException |
非法的设备状态异常 |
| NullPointException |
传说中的空指针异常,如果一个对象不存在,你有对这个对象使用点操作,那么就会出现该异常 |
| NumberFormatException |
把字符串转成数字失败时出现的数字格式异常 |
| AssertionError |
断言错误 |
| ExceptionInInitializerError |
试图初始化静态变量或者静态初始化块时抛出 |
| StackOverflowError |
栈溢出错误 |
| NoClassDefFoundError |
找不到指定的类错误 |
好了本讲就到这里,下节课我们讲自定义异常和调用栈。
阅读(1141) | 评论(0) | 转发(0) |