美文网首页
java异常处理简析

java异常处理简析

作者: zhanglbjames | 来源:发表于2017-05-25 13:29 被阅读0次

    1- try

    将可预见可能抛出异常的代码包含在try语句块中,也就是将一些会抛出异常的方法调用放在这个语句块,以便后续处理

    2- 异常

    1. Throwable

    错误和异常的超类(Error和Exception都继承自Throwable),包含了其线程创建时线程执行堆栈的快照,通过printStackTrace()方法打印堆栈跟踪数据信息。

    1. Exception

    被检查异常的顶级类,** 除了RuntimeException ,Exception类型的异常编译器会检查这种异常,需要对应的异常处理 **,否则会因为异常抛出导致程序异常终止,我们在开发的时候主要就是捕获这种异常。

    1. RuntimeException

    ** 运行时被检查异常,继承自Exception,但是这种异常发生在虚拟机运行期间,编译器不会检查这种异常 ,如果我们调用的方法可能抛出RuntimeException 类型的异常,但是并没有相应的try/catch进行处理,最后能通过编译,是因为编译器并不会在编译期间对这种异常进行检查。 如果代码会产生RuntimeException,则需要调整代码进行避免 **,如 ** ArithmeticException **

    1. Error

    继承自Throwable,** 编译器不会对错误进行检查 **。用于指示严重错误的发生,说明已经发生了无法挽回的错误,程序无法修复这种错误,直接导致程序因为错误而终止。如 ** VirtualMachineError **

    ** 下面重点介绍Exception类型的常用异常 **

    以下都是Exception的子类,表示特定的用途

    1. IllegalArgumentException 参数的值不合适
    2. IllegalStateException 参数的状态不合适
    3. NullPointerException 在null被禁止的情况下参数值为null
    4. IndexOutOfBoundsException 下标越界
    5. ConcurrentModificationException 在禁止并发修改的情况下,对象检测到并发修改
    6. UnsupportedOperationException 对象不支持客户请求的方法

    3- catch

    捕获try语句块中的Exception异常,并进行相应的处理
    1)编译的时候有些异常的捕获,如Exception,IllegalStateException,NullPointerException等(java.lang包的异常)并不要求try语句中含有抛出异常的方法调用;
    2)但是有些异常的捕获如ObjectStreamException,IOException等(java.io包的异常)并要求try语句中必须含有抛出异常的方法调用,否则编译错误

    1. 一个try语句块可以有多个catch子句来捕获不同的异常,但是** 同时只能捕获一个异常, 在异常发生的代码段,后续的代码得不到执行 **,转而执行对应的catch子句,并正常退出方法的调用。
      例子如下:
    例子1
    1. 通过捕获异常的超类来捕获
      例子如下:
    例子2
    1. catch中如果没有捕获到抛出的异常,则继续向上级调用者抛出异常
      例子如下:
    例子3

    4- throw 和 throws

    ** throw **

    用于在方法体内抛出异常,如果方法内部抛出异常,则此方法声明上可以通过throws声明抛出的异常,也可以什么都不声明,对抛出的异常并没有什么影响。
    比如


    例子4

    ** throws **

    用于方法声明上,声明可能抛出的异常,见例子4

    需要注意的是异常声明在继承时多态隐含的关系(** 对父类方法进行方法重写 ),虽然 异常声明不是方法签名的一部分 **

    1. ** 如果父类的方法没有声明抛出异常,子类覆盖的方法也不能声明抛出任何异常。**
    2. ** 如果父类的方法声明抛出特定异常E,子类覆盖的方法要么不声明抛出任何异常,要么声明抛出E异常或者E异常的子类(隐含的继承关系)。**

    5- finally

    表示的不管try方法块是正常执行完毕,还是抛出异常退出try语句块,finally都会在程序离开try语句块后执行,用来做最后的资源回收等操作。

    1. ** try中的return,catch中的return,finally中的return **
    例子5

    从中可以看出finally的return最终会覆盖try中的return语句,catch中没有捕获到异常,没有得到执行,** finally > catch > try 按照等级对return进行覆盖 **。

    1. ** try中的System.exit() **
    例子6

    ** 当try执行System.exit(0/1)都将立马退出程序,finally中的内容是得不到执行的。 **

    1. 守护进程中的finally

    守护进程与finally

    1. ** try/finally组合 **
    例子7
    setObj方法抛出异常,tryFinally方法调用setObj,并没有捕获异常,而是由tryFinally上级调用main方法来捕获,但是如果main方法没有捕获,则会因为异常抛出而没有处理而异常终止程序,参见AQS的acquireQueued方法

    总结

    避免将异常处理用于流程控制,也不能频繁的检查捕获不必要的异常,因为频繁异常的捕获和抛出(获取抛出异常线程的堆栈信息等操作)将消耗大量的系统性能,而且抛出的异常应尽量使用标准的异常类,来做到明确表达异常的含义。

    相关文章

      网友评论

          本文标题:java异常处理简析

          本文链接:https://www.haomeiwen.com/subject/ylvaxxtx.html