1、什么是异常
人生不如意事十之八九,对于程序来说,同样如此。程序员在写程序时,尽管考虑了各种意外情况,用了n个嵌套的if……else用于处理各种异常,但意外情况还是会发生的。为了提高程序的可靠性和安全性,异常机制应运而生。
首先看一下异常的定义吧。
异常:一个在程序执行期间发生的事件,它中断正在执行的程序的正常指令流。
OK,接下来,再打开Oracle公司的官网,查一下关于异常的相关知识点,我们找到了下面这些内容:
Public class Throwable extends Object implements Serializable,
The Throwable classis the superclass of all errors and exceptions in the Java language.
原来Throwable是所有错误和异常的基类,它涉及到了errors和exceptions。Throwable和errors以及exceptions这三者之间的关系究竟是什么呢?请看第一幅图。
(备注:此图参考于慕课网的相关JAVA课程资料)
真相大白,原来Throwable类包括了Error类和Exception类,其中,Error类和Exception类又进一步细分为各种异常类和错误类。那么,Error类和Exception类这二者的区别是什么呢?
Error类包括的错误情况,一般是与虚拟机相关,如系统崩溃、动态链接失败、虚拟机错误等,这种错误是无法恢复或无法被系统捕获的,其意味着程序的崩溃。而Exception类涉及到的异常则恰好相反,它们是可以被系统捕获的。由于Error类是无法捕获的,因此,我们这儿考虑的重点将放在Exception类,下面将重点介绍Exception类。
2、异常的分类
上图已告诉我们,异常类分为非检查异常和检查异常,其中,检查异常称为“Checked异常“,非检查异常即运行时异常,称为“Runtime异常”。所有的RuntimeException类及其子类的实例被称为Runtime异常。
Java认为Checked异常都是可以被修复的异常,所以程序中必须显式处理Checked异常,若没有处理,则程序在编译时会报错。
对于Runtime异常,它无须显式声明抛出,因为它在运行时由JVM抛出,不需要开发人员捕获和处理。当然,若程序员想捕获这类异常,也可以通过一些途径捕获到。
说了这么多,该进入本篇正话题了,即如何捕获和处理异常?
3、异常的处理
Java的异常处理是通过5个关键字来实现的:try、catch、 finally、throw、throws。
try块中放置可能产生异常的代码;
catch块中包括了处理异常的代码;
多个catch块后还可以跟一个finally块,finally块用于回收在try块里打开的物理资源,异常机制会保证finally块在大多数情况下被执行(特殊情况除外,后面会介绍)。
throw可以作为单独语句抛出一个具体的异常对象。
throws主要在方法签名中使用,用于声明该方法可能抛出的异常。
(备注:该图以及下面的几幅图均借鉴于百度文库中的某个PPT)
理论与实践相结合,介绍完了理论,该浅谈实践了。首先登场的是应用最为广泛的try……catch。
try……catch语法与switch……case语法非常相似,回顾一下switch……case语法。
switch ( 表达式 ){
case 常量表达式 1 : 语句/语句组 1
break;
case 常量表达式 2 : 语句/语句组 2
break;
……
case 常量表达式 n : 语句/语句组 n
break;
}
try……catch语法也同样如此:
try{
语句/语句组 1
}catch{
语句/语句组 2
}catch{
语句/语句组 3
}
……
catch{
语句/语句组 n
}
使用try/catch块捕获异常,分为三种情况:
第一种情况:
显然,若try块中的代码段不会产生异常,则catch块将不会被执行,直接执行catch块后面的代码段了。
第二种情况:
显然,当执行到try块中的代码段2时,会有异常产生,接下来会进入到catch块中的代码段4,恰好代码段4能够对该异常进行处理,则待处理完后,继续执行代码段5。
第三种情况:
当执行到try块中的代码段2时,会有异常产生,接下来会进入到catch块中的代码段4,若代码段4所能处理的异常类型不匹配,则程序中断运行。
说到这儿,你一定会有些疑惑,try块和catch块是如何关联的呢?
当编译器编译try块时出现异常,系统会自动创建一个异常对象(为了方便,此处我们给这个异常对象起个名——ex,ex中包括了异常类型和在程序发生异常时的状态),ex被传递给Java运行时环境(通常指代Java虚拟机,即JVM),这个过程称为抛出异常。
抛出异常后,Java运行时环境就会寻找能够处理该异常对象的catch块,若找到,则把该异常对象交给这个catch块来处理,这个过程称为捕获异常。若没有找到相应的异常处理器,运行时环境将终止执行,JAVA程序也将退出。如下图所示。
具体例子以及finally、throw和throws等知识点请看下篇介绍。