Java核心API之异常处理(上)
1、早期的异常处理机制
在Java编程语言出现之前,传统的异常处理方式常采用返回值来标识程序出现的异常情况,这种方式虽然为程序员所熟悉,但是有许多缺点:
首先,一个API可以返回任意的返回值,而这些返回值本身并不能解释该返回值是否代表该异常的具体情况,需要调用API的程序自己判断并解释返回值的含义。为了大家便于理解早期异常处理机制,小编简单编写伪代码如下:
public int dosome(){
编写一段业务逻辑代码;
if(出现第一种问题){
return 0;
}else if(出现第二种问题){
return 1 ;
}else if(出先第三种问题){
return 2;
}else{
return 3;
}
}
分析:早期的异常处理方式是添加返回值作为异常标识,但是调用者需要自己判断返回值的含义,正如上述伪代码,若出现错误返回值是0,调用者需要判断0具体是什么意义。

2、 其次,没有一种机制来保证异常情况一定会得到处理,调用者可以容易的忽略该返回值,需要调用者自己检测返回值并处理异常情况。这种方式增加代码的冗余,尤其在处理IO操作等容易出现异常时,代码中出现大量用于处理异常情况的switch分支语句,代码的可读性变得很差。伪代码如下:
public void invoking(){
处理业务逻辑调用dosome方法
int result = dosome();
switch(result){
case 0:
处理第一种错误;
break;
case 1:
处理第二种错误;
break;
case 2:
处理第三种错误 ;
break;
}
}
分析:调用者很容易忽略返回值的意义,还有代码中出现大量的switch语句块,代码的可读性非常差。

3、Java的异常处理机制
我们看到早期处理机制的方法,通过返回值标识异常具有诸多问题。现在让我们一起了解一下Java的异常机制的原理。
Java的处理异常方式很简单,见下面代码:
try{
...
} catch(Exception e) {
...
} finally {
...
}
Java要求将可能出现异常的代码放在try语句块中,程序会从导致异常的代码出跳出,java虚拟机检测寻找和try关键字匹配的处理该异常的catch块,如果找到,将控制权交到catch块中的代码,然后继续执行后面的程序。如果没有找到处理该异常的catch块,执行finally代码块中的代码,然后中止当前线程。
PS:线程的知识下节会继续讲解。

4、异常的捕获和处理
Java异常机制中定义有Throwable类,Exception和Error是其派生的两个子类。
Exception表示由于网络故障、文件损坏、设备错误、用户输入非法字符等原因导致的异常。
Error表示Java运行时环境自身出现的错误,如内存溢出等。
分析:作为一名程序员,在日常工作中常常需要处理的就是Exception异常,而Error异常是Java环境本身错误,我们很少处理。在项目中,Java运行环境安装和部署往往是由运维工程师完成的,软件工程师主要完成项目开发等,所以作为一名程序员,要求能够处理一般常见的Exception,或者规避这些异常。
5、使用try,catch语句处理异常
将可能出现异常的代码放在try{...}代码块中,该代码块中可能会抛出一种或几种类型的异常对象,try语句块后面的catch语句块分别对这些异常对象进行处理。在catch中声明的异常对象封装了异常事件发生的信息,在catch语句块中可以获取这些信息。
如果没有产生异常,跳过catch语句块其中的内容都被忽略不被执行,继续执行后续代码。
实例代码如下:
/*
* try-catch()
* 处理异常
*/
@Test
public void testTryCatch(){
FileInputStream fis = null;
try {
//如果找不到文件test.txt则会抛出异常
fis = new FileInputStream("test.txt");
} catch (FileNotFoundException e) {
//catch语句块中捕获异常
}
}

6、catch可以用来捕捉多个异常
一个try语句块可以有一个或多个catch语句块,可以处理try语句块中产生的多个不同类型的异常。
注意一点,catch从上至下捕获异常类型的顺序应该是先子类后父类。试想,如果catch铺货异常类先父类后子类,那么catch只能捕获父类的异常,不会捕获捕获子类的异常。

7、finally的使用介绍
finally语句为异常处理提供一个统一的出口,使得在控制流程转到当前程序其他部分以前,能够对程序的状态作统一管理。
不管try语句块中的程序是否抛出异常,finally语句块的代码必须执行。
一般在finally语句块中进行资源的释放,如可以关闭文件的资源,删除临时文件等。
