ITEEDU

Java Gossip: 简介例外处理

在还没有学习例外处理之前,如果您要撰写一个除法程序,并由使用者输入除数与被除数,由于被除数除以0没有意义,所以之前可能必须像以下这样避免错误:

if(b != 0)
System.out.println(a / b);
else
System.out.println("除数不能为0");

这样的方式过去在一些程序语言中会很常被利用,利用判断式来避免错误的发生,然而这样的方式会让错误处理与程序的处理逻辑混在一起,使得程序难以阅读,而 由于使用了一些判断式,即使有一些很少发生的错误,也都必须一视同仁的进行判断检查,这会使得程序的执行效能受到一定程度的影响。

Java的例外处理机制可以协助我们捕捉程序执行时期的错误,它用来处理一些系统可以恢复的错误,例外(Exception)是Java中定义的一种对象数据型态,在特定错误发生时会丢出例外对象,我们可以捕捉这些例外并加以处理,避免程序可能的错误发生。

Java的例外处理藉由"try"、"catch"、"finally"三个关键词组合的语言来达到,其语法基本结构如下:

try {
	// 陈述句
}
catch(例外型态 名称) {
	// 例外处理
}
finally {
	// 一定会处理的区块
}

一个"try"所包括的区块,必须有对应的"catch"区块,它可以有多个"catch"区域,而"finally"可有可无,如果没有定义"catch"区块,则一定要有"finally"区块。

先来看个实例,了解如何使用try...catch来处理使用者输入的错误:

UseException.java
import java.io.*;
public class UseException {
	public static void main(String[] args) {
		try {
			int input;
			BufferedReader buf = new BufferedReader(
			new InputStreamReader(System.in));
			System.out.print("请输入整数: ");
			input = Integer.parseInt(buf.readLine());
			System.out.println("input x 10 = " + (input*10));
		}
		catch(IOException e) {
			System.out.println("I/O错误");
		}
		catch(NumberFormatException e) {
			System.out.println("输入格式有误");
		}
	}
}

例外处理是程序在执行但发生错误并无法处理时,会丢出一个例外对象,在这个程序中,您特意 使用 BufferedReader 取得输入,当使用 BufferedReader类别时,若发生I/O错误会丢出IOException例外,这个例外您必须处理。

您试着从使用者输入取得一个整数值,由BufferedReader对象所读取到的输入是个字符串,您使用Integer类别的 parseInt()方法试着剖析该字符串为整数,如果无法剖析,则会发生错误并丢出一个NumberFormatException例外对象,当这个例外丢出后,程序会离开目前执行的位置,而如果设定的"catch"有捕捉这个例外,则会执行对应区块中的陈述句,注意当例外一但丢出,就不会再回到例外的丢出点了。

来看看这个程序的执行范例:

$ java UseException 
请输入整数: 10 
input x 10 = 100 
$ java UseException 
请输入整数: XX 
输入格式有误

如果程序中设定有"finally"区块,则无论例外是否有发生,则一定会执行"finally"区块中所定义的陈述句,"finally"区块使用时机 的例子之一,就是当您开启了某个档案时,在读/写的过程中发生错误,在使用"catch"区块处理相对应的例外之后,最后在"finally"区块中定义 一些关闭档案的动作,让关闭档案的动作一定会被执行。

使用例外处理的好处是您可以将程序逻辑与错误处理分开,使得程序易于撰写、阅读与维护,由于例外处理是在程序执行时发生错误,而没有办法处理之时才产生例外对象,所以与使用判断式来避免例外的方式比起来,例外处理会有比较好的执行效能。