Java中的异常

  在程序运行时,发生了期望之外的情况,它阻止了程序按照程序员的预期正常执行,这就是异常。

  对于异常,Java提供了优秀的解决办法:异常处理机制。常处理机制能让程序在异常发生时,按照代码的预先设定的异常处理逻辑,针对性地处理异常,让程序尽最大可能恢复正常并继续执行,且保持代码的清晰。

  Java中的异常可以是函数中的语句执行时引发的,也可以是程序员通过throw语句手动抛出的。只要在Java程序中产生了异常,JVM就会创建一个对象,将异常的具体信息保存到这个对象中,通过throw关键字将这个对象抛出去。如果这个函数中书写了处理异常的代码,就执行这个代码;如果没有,就将这个异常返回给函数的调用者,并结束这个函数。如果函数的调用者书写了处理异常的代码,就执行这个代码;如果没有,就将异常发生的位置也保存到对象中,然后将对象继续向上一级抛出。如果一直没有处理异常的代码,最终这个对象就会抛给JVM。JVM就会将对象中保存的异常信息输出到控制台,然后结束程序。

异常的体系和分类:

     

从图中可以看到,Throwable类是所有错误和异常的顶层父类。

错误:Error类及其子类,一般是JVM自身的错误(系统错误),程序员通过代码无法处理。因此我们一般要关心能够通过代码处理的Exception类及其子类。

异常:Exception类及其子类,一般是程序运行时发生的不被期望的事情。可以被Java异常处理机制处理。

Exception类又分为运行异常类(非检查异常类)和非运行异常类(可检查异常类)。

RuntimeExcetion类及其子类是运行异常类(非检查异常)。它是在程序运行时有解释器引发的各种异常,可以发生在任何地方且出现频率很高。因此为了避免巨大的系统资源开销,编译器不会对这类异常进行检查。对于这类异常我们可以编写代码处理,也可以不处理。这类异常出现,一般是我们的代码写的有问题,可以通过修正代码来避免。如算术异常(除0)ArithmeticExecption,类型强制转换错误 ClassCastException,空指针异常 NullPointerException,角标越界异常 ArrayIndexOutOfBoundsException等等。

除RuntimeException类及其子类外,Exception类的其他子类都是非运行异常(可检查异常)。它在编译的时候就会由编译器进行检查。这类异常必须进行异常处理,如果不处理,则编译不通过。这类异常是由于程序可能被运行在各种未知的环境下,而程序员无法干预用户如何使用他编写的程序,于是程序员就应该为这样的异常时刻准备着。这类异常有SQLException , IOException,ClassNotFoundException 等。

处理异常的方式:

在Java编写代码处理可检查异常时,有两种处理方式。

1、通过Throws关键字声明可能发生的异常,交给函数的调用者去处理。

2、通过try{ } catch{ } finally { } 语句来捕捉并处理异常。

需要注意的是:

1、当声明异常时,

如果一个函数中会抛出多个异常,每一个异常都要处理;

也可以声明一个它们共同的父类;

2、当捕捉异常时,

如果有多个异常,要多次分别捕获,分别处理;使用多个catch

如果处理代码一样,可以使用一个catch捕获;

如果同一个try块下的多个catch异常类型有父子关系,应该将子类异常放在前面,父类异常放在后面,这样保证每个catch块都有存在的意义。

 

finally块不管异常是否发生,只要对应的try执行了,则它一定也执行。只有一种方法让finally块不执行:System.exit()。因此finally块通常用来做资源释放操作:关闭文件,关闭数据库连接等等。

在同一try...catch...finally块中 ,如果try中抛出异常,且有匹配的catch块,则先执行catch块,再执行finally块。如果没有catch块匹配,则先执行finally,然后去外面的调用者中寻找合适的catch块。

在同一try...catch...finally块中 ,try发生异常,且匹配的catch块中处理异常时也抛出异常,那么后面的finally也会执行:首先执行finally块,然后去外围调用者中寻找合适的catch块。

继承中方法重写的异常:

子类重写的函数不能比父类中的函数声明更多的编译异常且只能声明这个异常或者它的子异常;

重写函数声明运行时异常,对方法重写没有影响。

自定义异常:

 在Java中已经已经有了一些异常类来描述程序中常出现的问题。除此之外,我们还可以自定义异常。

步骤:

1、自定义一个异常类,继承ExceptionRuntimeException;

2、给这个类提供一个构造函数,在构造函数中用super调用父类有参函数。

posted on 2018-08-14 00:04  常建明  阅读(329)  评论(0编辑  收藏  举报

导航