每一种开发语言都有自己的异常处理机制,Java也不例外。不过编程语言不断的发展的同时,异常处理机制也是不断的完善起来。这篇文章就简单记录Java的异常处理机制,文章共分为三部分,分别是概念、分类和处理。
概念
Java异常是Java提供的用于处理程序中错误的一种机制,而所谓的错误是在程序运行的过程中发生的一些异常事件。Java对异常的操作有两种方式,一是抛出异常,而是捕获异常。
Java程序的执行过程中如出现异常事件,可以生成一个异常类对象,该异常类对象封装了异常事件的信息并将被提交给Java运行时系统,这个过程称为抛出异常(throw)。
当Java运行时系统接收到异常对象时,会寻找能处理这一异常的代码,并把当前异常对象交给其处理,这个过程称为捕获异常(catch)。
分类
在java.lang包中有一个Throwable类,意思是能被抛出的,Java所有的错误和异常都继承这个类。 如图中所示,Error和Exception两个类都继承于Throwable类。Error是系统处理不了的错误,Exception是系统能够处理的异常。Exception的子类中,RuntimeException属于运行时异常,属于经常出现的错误,可以不被catch,但是其余的Exception抛出的异常是必须catch的。
在Java捕获异常时,需要先捕获作为子类的异常,然后再捕获作为父类的异常,如果先捕获父类的异常,那么其实它的子类同样都被捕获到了,就不需要再捕获子类的异常了。
处理
Java异常捕获后会做出相应的处理,这就是捕获处理。在这个过程中,有五个关键字,分别是try、catch、throw、throws、finally。
try语句
try{...}语句指定了一段代码,该段代码就是一次捕获并处理异常的范围,也就是说你认为哪一段代码可能出异常,或者这个方法必须抛异常,那么就放在try语句块中就可以了。
catch语句
catch语句是紧跟在try语句后面的,在catch语句块中是对异常进行处理的代码,try语句后可以有一个或多个catch语句,用于处理不同类型的异常对象。catch中声明的异常对象封装了异常事件发生的信息,在catch语句块中可以使用这个对象的一些方法来获取异常信息,比如getMessage()方法可以得到有关异常事件信息,printStackTrace()方法可以跟踪异常事件发生时堆栈的内容。
finally语句
finally语句是异常处理的统一出口,也就是说try中的程序不管有没有异常,finally中指定的代码都要执行。通常在finally中进行资源清除的工作 ,比如删除临时文件,关闭打开的文件,这样即使程序抛异常,也不会影响这些资源的使用。
throw关键字
throw关键字用于方法体内部,用来抛出异常,如果抛出了检查异常,则还应该在方法头部声明方法可能抛出的异常类型。该方法的调用者也必须在检查处理抛出的异常。
throws关键字
throws关键字用于方法体外部的方法声明部分,用来声明方法可能会抛出的异常。仅仅当抛出了检查异常,该方法的调用者才必须处理或者重新抛出该异常。如果调用者无法处理该异常,则应该继续抛出,而不是只做简单处理。
下面看部分代码的示例:
<span style="font-family:KaiTi_GB2312;font-size:18px;"><span style="font-family:KaiTi_GB2312;font-size:18px;"> void m(int i) throws ArithmeticException { if(i==0) throw new ArithmeticException("被除数为0"); //方法体内部抛出异常 } void f2() throws IOException { //方法体外部声明抛出的异常 try { //try语句包含可能抛异常或者必须抛异常的代码段 f(); } catch (FileNotFoundException e) { //catch语句捕获抛出的异常并作出简单处理 System.out.println(e.getMessage()); //catch语句捕获异常后打印异常的信息 } catch (IOException e) { e.printStackTrace(); //catch语句捕获异常后打印堆栈信息 } f(); }</span></span>
总结
对异常做处理时,要尽量早的抛出异常,能在编译时抛出异常就尽量不要等到运行时,这样更方便程序员的处理。在重写某一方法时,如果该方法必须抛出某类异常,那么重写该方法的方法应该抛出与原方法相同的异常类型或者不抛出异常。方法调用的级别不同,所抛出的异常的级别也是不同的。