异常处理

本文深入探讨Java中的异常处理机制,包括异常的分类、处理语法以及常见异常实例。并通过一个具体示例展示了如何在Java程序中利用异常处理确保代码的健壮性和可靠性。

软件开发中有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 找不到指定的类错误

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值