异常处理

软件开发中有80%的工作是用来检查和处理错误,而检查并处理错误很多时候是一件枯燥无趣的事情,如果在语言级别提供一些帮助的话,会减轻一些程序员的负担。

而Java提供了一套比较优秀的异常处理机制: 
    1、使开发人员不必编写特殊代码来测试返回值就能发现问题, 
    2、在语法结构就把正常的代码和异常处理的代码清晰的分开来, 
    3、允许我们使用相同的异常处理代码来处理一定范围内的所有异常。 
以期产生一种高效的、有组织的异常处理方式。

1、异常及异常的分类

异常是指在程序中出现的异常状况,在Java中异常被抽象成一个叫做Throwable的类。

其中如果程序出错并不是由程序本身引起的,而是硬件等其他原因引起的,我们称之为Error,一般情况下Error一旦产生,对程序来说都是致命的错误,程序本身无能为力,所以我们可以不对Error作出任何处理和响应。

异常如果是由程序引起的我们称之为Exception,Exception又分两种,我们把运行时才会出现的异常叫做 RuntimeException,RuntimeException我们不好在程序编写阶段加以事先处理,而其他异常则可以在程序编写和编译阶段加以事先检查和处理,我们把这种异常叫做检验异常。

程序只需要捕捉和处理检验异常。

相应的我们把除检验异常(可检查异常)之外的异常称之为非检验异常,包括Error和RuntimeException ,非检验异常可以捕捉也可以不捕捉,更多的时候我们不捕捉,因为捕捉了我们也没办法处理,譬如程序运行时发生了一个VirtualMachineError异常,虚拟机都出错了,作为运行在虚拟机内的程序又有什么办法处理呢?

下面我们用图来表示一下上面讲述的内容:

image 
 

2、异常的处理 try ^ catch ^ finally

异常相关的处理语法可以用下图概括一下:

image

异常处理的几条规则:

  1. try用于定义可能发生异常的代码段,这个代码块被称为监视区域,所有可能出现检验异常的代码写在这里。
  2. catch代码段紧跟在try代码段后面,中间不能有任何其他代码。
  3. try后面可以没catch代码段,这实际上是放弃了捕捉异常,把异常捕捉的任务交给调用栈的上一层代码。
  4. try后面可以有一个或者多个catch代码段,如果有多个catch代码段那么程序只会进入其中某一个catch。
  5. catch捕捉的多个异常之间有继承关系的话,要先捕捉子类后捕捉父类。
  6. finally代码段可以要也可以不要。
  7. 如果try代码段没有产生异常,那么finally代码段会被立即执行,如果产生了异常,那么finally代码段会在catch代码段执行完成后立即执行。
  8. 可以只有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;
009  
010 public class Bank02 {
011  
012     //用ArrayList存储储户信息
013     List<String[]> list = new ArrayList<String[]>();
014  
015     //用初始化块准备一些测试数据
016     {
017         String[] account = { "10001""aya""111111""60000" };
018         list.add(account);
019         account = new String[] { "10002""bean""222222""40000" };
020         list.add(account);
021     }
022  
023     //用BufferedWriter和BufferedReader读写文件
024     BufferedWriter bw;
025     BufferedReader br;
026  
027     // 字符串数组转字符串,试图写一个通用方法
028     public static String arrayToString(String[] input, String space) {
029         String output = "";
030         for (int i = 0; i < input.length; i++) {
031             output += input[i] + space;
032         }
033         return output.substring(0, output.length() - 1);
034     }
035  
036     // 写文件
037     public void writeFile() {
038         try {
039             //try代码块又称之为"监视区域",表示有可能出问题闹异常的代码写在这里
040             bw = new BufferedWriter(new FileWriter("bank.txt"));
041             for (String[] account : list) {
042                 bw.write(arrayToString(account, " "));
043                 bw.newLine();
044             }
045             bw.flush();
046         catch (IOException e) {
047             //可以使用一个catch来捕捉异常
048             //doSomething
049  
050             //打印出异常的堆栈踪迹
051             e.printStackTrace();
052         finally {
053             //finally提供了一个在正常时和异常时都需要执行的代码段,在这里可以进行一些资源的释放工作,数据的清理工作
054             try {
055                 bw.close();
056             catch (IOException e) {
057                 e.printStackTrace();
058             }
059         }
060  
061     }
062  
063     // 读文件
064     public void readFile() {
065         try {
066             //try代码块又称之为"监视区域",表示有可能出问题闹异常的代码写在这里
067             br = new BufferedReader(new FileReader("bank.txt"));
068             String temp = "";
069             list.clear();
070             while ((temp = br.readLine()) != null) {
071                 list.add(temp.split(""));
072             }
073         catch (FileNotFoundException e) {
074             //可以使用一个catch来捕捉异常
075             //doSomething
076  
077             //打印出异常的堆栈踪迹
078             e.printStackTrace();
079         catch (IOException e) {
080             //也可以用一组catch来捕捉多个异常,如果多个异常之间有继承关系,那么父类异常写下面
081             e.printStackTrace();
082         }finally{
083             //finally提供了一个在正常时和异常时都需要执行的代码段,在这里可以进行一些资源的释放工作,数据的清理工作
084             try {
085                 br.close();
086             catch (IOException e) {
087                 e.printStackTrace();
088             }
089         }
090     }
091  
092     public static void main(String[] args) {
093         //创建一个bank对象
094         Bank02 bank = new Bank02();
095         //写入数据
096         bank.writeFile();
097         //读取数据
098         bank.readFile();
099     }
100  
101 }

3、常见异常

ArrayIndexOfBoundsException 数组下标越界异常
ClassCastException 强制转换类失败异常
IllegalArgumentException 方法参数类型传入异常
IllegalStateException 非法的设备状态异常
NullPointException 传说中的空指针异常,如果一个对象不存在,你有对这个对象使用点操作,那么就会出现该异常
NumberFormatException 把字符串转成数字失败时出现的数字格式异常
AssertionError 断言错误
ExceptionInInitializerError 试图初始化静态变量或者静态初始化块时抛出
StackOverflowError 栈溢出错误
NoClassDefFoundError 找不到指定的类错误

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值