在还没有学习例外处理之前,如果您要撰写一个除法程序,并由使用者输入除数与被除数,由于被除数除以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来处理使用者输入的错误:
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"区块中定义 一些关闭档案的动作,让关闭档案的动作一定会被执行。
使用例外处理的好处是您可以将程序逻辑与错误处理分开,使得程序易于撰写、阅读与维护,由于例外处理是在程序执行时发生错误,而没有办法处理之时才产生例外对象,所以与使用判断式来避免例外的方式比起来,例外处理会有比较好的执行效能。