Java 异常处理相关

相关类的结构以下所示

  • java.lang.Objectjava

    • java.lang.Throwable数组

      • java.lang.Error
      • java.lang.Exception函数

        • java.lang.RuntimeException

Throwable类

  • Throwable 类是Java语言中全部错误和异常的超类,只有当一个对象直接或者间接的是此类的实例时,Java才能经过throw语句抛出异常,一样,只有这种类才能被try……catch语句捕获进行处理
  • Throwable类的子类Error是错误,不是程序能够处理的,通常会是内存不足,线程终止,Java虚拟机运行错误等,只能听之任之,JVM一般会kill掉这个进程
  • Throwable类的子类Exception是异常,是程序能够处理的,进一步分为CheckedException 和 UncheckedException性能

    • CheckedException发生在编译阶段,代码语句必须使用try……catch或者throws,不然没法进行编译,好比StreamTokenizer必须声明抛出异常IOException,除了Runtime Exception类集以外,其余的Exception类集都是CheckeException
    • UncheckedException发生在程序的运行阶段,通常来讲具备不肯定性,不容易定位和DEBUG

Exception类

  • 该类指出了合理的应用程序想要捕获的异常条件,有两个参数,默认构造能够是两个可选参数,一个是详细信息,一个是异常缘由,分别对应下述四个构造方法,分别于super对应线程

    • public Exception()
    • public Exception(String message)
    • public Exception(String message, Throwable cause)
    • public Exception(Throwable cause)

RuntimeException类

  • RuntimeException是那些在Java 虚拟机正常运行期间抛出的异常的超类,属于uncheckedException,好比说发生数组越界,空指针等逻辑引发的问题
  • 可能在执行方法期间抛出,可是没有被捕获的RuntimeException的任何子类都不用在throws子句中声明
  • 包含四个构造方法指针

    • RuntimeException()
    • RuntimeException(String message)
    • RuntimeException(String message, Throwable cause)
    • RuntimeException(Throwable cause)

try - catch - finally

  • 在try代码片断中,包含着有可能抛出异常的语句,若是无异常,则直接跳到finally代码块,不然相应的捕获异常,执行catch代码块的内容
  • 不管是否try代码块发生异常,finally都会被执行,能够在这里进行一些接口的close操做等
  • 若是代码中显式的声明了某一个异常类型,则异常处理机制不会显示这个异常是在哪里抛出的,若是是没有声明异常遭遇中断,异常处理会显示出处
  • 每个catch按照书写的前后依次匹配执行,一旦亦常被某一个catch捕获,则必不会被其余的catch捕获处理
  • 当try代码块或者catch代码块中包括return语句的时候,finally代码块将会在return以前被强制执行,finally不被执行仅仅当下列条件被知足:对象

    • 代码在finally代码块以前即发生错误
    • 代码在finally代码块以前进行了System.exit()
    • 当前线程因为某种状况丢失
    • 关机,或者各类奇葩的可能条件

throw 和 throws

  • throws 是方法抛出异常的声明,表示一个预动做,说明下方方法可能会抛出异常,throws不作其余处理,仅仅是上交异常到调用,方法中抛出的任何异常都必须有throws声明,除非是将交由运行时系统自动抛出的RuntimeException
  • throw是抛出异常,是一个明确的动做,必须与try……catch或者throws一块儿使用,抛出的只能是Throwable的类集中的类,若是全部的方法都将异常往上层调用者抛,那么JVM最后的处理就是打印异常消息和堆栈信息

自定义异常类型

通常来讲,套路以下:继承

  1. 定义一个类,继承自Throwable或者某一个子类
  2. 构造方法,或者直接使用super的构造方法
  3. throws声明,在代码块的某处throw该异常类
  4. catch到抛出的异常进行处理

异常链机制

  • 当异常较少的时候,咱们能够对每个异常进行try 和catch, 可是若是出现多个异常,显然经过一个Exception处理全部异常的方式会增长维护代码DEBUG的困难度,因此咱们须要将异常信息进行封装,而后捕获咱们的异常封装类便可
  • 异常的处理方式有两种,一种是throws抛出异常后交给上级去处理,另外一种就是使用try和catch进行具体的修正处理,异常链的处理采用第一种方式,在try ……catch的catch代码块中不作任何处理,惟一的动做就是抛出封装好的异常信息,而后会有throws抛出该异常,递归的每一层都如此控制异常抛出,就造成了一条异常链
  • 若是咱们想要在捕获到一个异常后抛出另一个异常,那么,咱们能够调用Throwable类集的getCause()方法,获得类中的cause参数,这个参数保存的就是原始存有的异常信息,也就是说cause是致使抛出该throwable的throwable
  • 保留有异常链的catch代码块中可使用Throwable的printStackTrace()方法来打印整个异常信息
  • getCause() 返回由一个须要Throwable的构造方法提供的cause,或者是在建立Throwable以后经过initCause()来设定cause,子类没必要要重写,也没必要重写printStackTrace()
  • printStackTrace()方法会将对象的堆栈跟踪输出到输出流,做为System.err的值

几个建议

  • 尽可能在try中不要包含太多的代码,缩小异常范围圈
  • 若是有的接口即便有异常也照样要运行,那么应该使用finally
  • 缩小catch捕获的异常,尽可能使catch捕获明确的单个异常
  • 抛出异常的时候,尽可能包含易读易懂的描述和名称
  • 不在构造函数中抛出异常,不在finally代码块中处理返回
  • 不要老抛出异常,会下降Java的效率和系统的性能
相关文章
相关标签/搜索