Java异常(三十七)
很多事件并非总是按照人们自己设计意愿顺利发展的,经常出现这样那样的异常情况。
例如: 计划周末郊游,计划从家里出发→到达目的→游泳→烧烤→回家。但天有不测风云,当准备烧烤时候突然天降大雨,只能终止郊游提前回家。“天降大雨”是一种异常情况,我们的计划应该考虑到这样的情况,并且应该有处理这种异常的预案。
计算机程序的编写也需要考虑处理这些异常情况。异常(exception)是在运行程序时产生的一种异常情况,已经成为了衡量一门语言是否成熟的标准之一。目前的主流编程语言,如C++、c#、Ruby和python等大都提供了异常处理机制。
异常简介
Java 中的异常又称为例外,是一个在程序执行期间发生的事件,它中断正在执行程序的正常指令流。为了能够及时有效地处理程序中的运行错误,必须使用异常类,这可以让程序具有极好的容错性且更加健壮。
Exception 类是 Throwable 类的子类。除了Exception类外,Throwable还有一个子类Error 。所有的异常类都是从 java.lang.Exception 类继承的子类。
Error 用来指示运行时环境发生的错误。Java 程序通常不捕获错误。错误一般发生在严重故障时,它们在Java程序处理的范畴之外。例如:JVM 内存溢出等等。
在 Java 中一个异常的产生,主要有如下三种原因:
- Java 内部错误发生异常,Java 虚拟机产生的异常。
- 编写的程序代码中的错误所产生的异常,例如空指针异常、数组越界异常等。
- 通过 throw 语句手动生成的异常,一般用来告知该方法的调用者一些必要信息。
Java 通过面向对象的方法来处理异常。在一个方法的运行过程中,如果发生了异常,则这个方法会产生代表该异常的一个对象,并把它交给运行时的系统,运行时系统寻找相应的代码来处理这一异常。
我们把生成异常对象,并把它提交给运行时系统的过程称为拋出(throw)异常。运行时系统在方法的调用栈中查找,直到找到能够处理该类型异常的对象,这一个过程称为捕获(catch)异常。
处理异常
try-catch 以及 try-catch-finally
try {
//一些会抛出异常的方法
} catch (Exception e) {
//处理该异常的代码块
}
运行结果:
如果try块中的方法会抛出很多种类型的异常,这种情况该如何处理?
—— 用多重catch块语法(用多个catch块来捕获多种不同类型的异常,并对其进行相应的处理)
编写多重catch语句块需要注意顺序问题,要按照先子类后父类(先小后大)的顺序来编写。因为当程序抛出异常的时候,异常处理系统会就近寻找匹配的异常处理程序,而子类继承于父类,针对于父类的异常处理程序对于子类也是适用的。
运行结果:
有时候用try-catch语句块处理完异常后,还需要进行一些善后工作,如:关闭连接、关闭一些已经打开的文件等等。该如何做这种善后工作呢?
—— 用finally语句块
try {
//一些会抛出异常的方法
} catch (Exception e) {
//处理该异常的代码块
} catch (Exception2 e) {
//处理Exception2的代码块
} ...(n个catch块)... {
} finally {
//最终将要执行的一些代码
}
Java中的异常抛出
throw - 将产生的异常抛出(动作)
throws - 声明将要抛出何种类型的异常(声明)
public void 方法名(参数列表)
throws 异常列表 {
//调用会抛出异常的方法或者:
throw new Exception();
}
自定义异常
class 自定义异常类 extends 异常类型{
}
//自定义异常要么继承Java类库中意思相近的异常,要么直接继承所有异常的基类:Exception
Java中的异常链
运行结果:
实际应用中的经验与总结
1.处理运行时异常时,采用逻辑去合理规避同时辅助try-catch处理
2.在多重catch块后面,可以加一个catch(Exception)来处理可能会被遗漏的异常
3.对于不确定的代码,也可以加上try-catch,处理潜在的异常
4.尽量去处理异常,切忌只是简单的调用printStackTrace()去打印输出
5.具体如何处理异常,要根据不同的业务需求和异常类型去决定
6.尽量添加finally语句块去释放占用的资源