博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

Java异常处理机制

Posted on 2017-02-28 15:41  LZJ_name  阅读(139)  评论(0编辑  收藏  举报

一. 两种异常

RuntimeException:非检查异常,如NullPointerException,IndexOutBoundsExceptio,Java编译器不要求必须进行异常捕获或者抛出声明,由程序员自行决定

非运行时异常:检查异常,Java编译器强制程序员必须进行捕获处理,如IOException,SQLException,如果不进行捕获或者抛出声明处理,编译都不会通过

二. 三种方法

1)try..catch进行异常捕获

2)在方法体外利用throws抛出异常,告知调用者这段代码可能会出现异常

2.1 抛出的异常是非运行异常,此方法的调用者必须显示的用try..catch捕获或是继续向上抛出异常

2.2 若是运行时异常,此方法的调用者可以选择性的进行异常捕获处理

3)代码块中用throw手动抛出一个异常对象

3.1 抛出的异常对象是非运行时异常,此方法调用者需显示的用try..catch进行捕获或者向上抛出异常

注:

被try块包围的代码说明这段代码可能会发生异常,一旦发生异常,异常变回被catch捕获到,然后需要在catch块中进行异常处理

throw和throws是抛出异常,让调用者去处理,自己不进行具体的处理

3.2 运行时异常,调用者可以选择性的进行异常捕获

三. 几个关键字

1)try用来包围可能出现的异常逻辑代码,无法单独使用,必须配合catch或者finally使用,可以有一下形式

try…catch…,try…finally…,try…catch…finally…

try块只能有一个,catch块可以有多个,finally块是可选的,最多能有一个,catch是对异常进行处理,在有异常的情况下会进入catch块,finally块无论什么情况下都会执行的;当存在多个catch块的时候,是按catch块的先后顺序进行匹配的,一旦异常与其中一个catch块匹配,则不会与后面的catch块进行匹配

注:在使用try...catch...finally,要慎重再finally块中使用return,因为finally中的return会覆盖已有的返回值。

2)throws出现在方法的声明中,表示该方法可能会出现异常,然后交给上层调用它的方法程序进行处理,允许后面跟多个异常类型;

表示会出现异常的可能性,并不一定会产生异常

3)throw只会出现在方法体中,当方法在执行的过程中遇到某种异常情况,将异常消息封装为异常对象,然后throw出去;(throw可以进行异常类型转换)

一定是出现了某种异常,然后抛出突出刚

四. 异常抛出声明

子类重写父类方法,确定异常抛出声明的类型的三点原则:

1)父类的方法没有声明异常,子类在重写该方法的时候不能声明异常

2)父类方法声明了一个异常exception1,则子类在重写该方法的时候声明的异常不能是exception1的父类

3)如果父类声明的异常只有非运行时异常(运行时异常),则子类在重写该方法的时候声明的异常也只能有非运行时异常(运行时异常),不能有运行时异常(非运行时异常) 

五. 注意

1)慎重使用异常,不要用异常区控制程序的流程

2)切忌使用空catch块,相当于在捕获了异常后什么都不做,相当于忽略了这个异常,意味着在程序中隐藏了错误和异常,并且很可能导致程序出现不可控的执行结果。如果非常肯定捕获到的异常不会以任何方式对程序造成影响,最好用Log日志将该异常进行记录,以便日后方便更新和维护。

3)异常抛出的旋转(检查异常还是非检查异常)

4)注意catch块的顺序,不要把上层类的异常放在最前面的catch块上,否则对于下层catch块永远无法匹配

5)不要将提供给用户看的信息放在异常信息里,比较好的方式是将所有错误提示信息放在一个配置文件中统一管理。

6)避免多次在日志中记录同一个异常,否则可能无从查找异常发生的根源

7)异常处理尽量放在高层进行,尽量将异常抛给上层调用者。若在每个出现异常的地方都直接进行处理,会导致程序异常处理流程混乱,不利于后期维护和异常错误排查

8)在finally中释放资源,若有使用文件读取,网络操作以及数据库操作等,记得在finally中释放资源。这样可以使程序占用更少的资源,也可以避免因为资源未释放二发生的异常。