Java的异常处理机制

作者: 吴七禁 | 来源:发表于2017-12-04 17:21 被阅读35次

    参考文献:Java Platform Standard Edition 6 API 规范

    Throwale

    Throwable 类是 Java 语言中所有错误或异常的超类。只有当对象是此类(或其子类之一)的实例时,才能通过 Java 虚拟机或者 Java 的 throw 语句抛出。类似地,只有此类或其子类之一才可以是 catch 子句中的参数类型。

    Error

    Error 是 Throwable 的子类,用于指示应用程序不应该试图捕获的严重问题。Error 也叫系统级异常,它是为无法预计的,程序无法处理的异常错误,表示运行应用程序过程中出现了较严重问题。一般情况都是在JVM上出现了问题。

    在执行该方法期间,无需在其 throws 子句中声明可能抛出但是未能捕获的 Error 的任何子类,因为这些错误是不确定的不会重复出现的。

    Error有如下常见且重要的子类:

    • AnnotationFormatError
      当注释解析器试图从类文件读取注释并确定注释出现异常时,抛出该错误。

    • IOError
      当发生严重的 I/O 错误时,抛出此错误。

    • ThreadDeath
      调用 Thread 类中带有零参数的 stop 方法时,受害线程将抛出一个 ThreadDeath 实例。
      仅当应用程序在被异步终止后必须清除时才应该捕获这个类的实例。如果 ThreadDeath 被一个方法捕获,那么将它重新抛出非常重要,因为这样才能让该线程真正终止。
      如果没有捕获 ThreadDeath,则顶级错误处理程序不会输出消息。
      虽然 ThreadDeath 类是“正常出现”的,但它只能是 Error 的子类而不是 Exception 的子类,因为许多应用程序捕获所有出现的 Exception,然后又将其放弃。

    • LinkageError
      LinkageError 的子类指示一个类在一定程度上依赖于另一个类;但是,在编译前一个类之后,后一个类发生了不相容的改变。它一共有7个直接子类。

    • VirtualMachineError
      当 Java 虚拟机崩溃或用尽了它继续操作所需的资源时,抛出该错误。子类有:InternalError(该异常指示 Java 虚拟机中出现一些意外的内部错误),OutOfMemoryError(因为内存溢出或没有可用的内存提供给垃圾回收器时,Java 虚拟机无法分配一个对象,这时抛出该异常),StackOverflowError(当应用程序递归太深而发生堆栈溢出时,抛出该错误),UnknownError(当 Java 虚拟机中出现一个未知但严重的异常时,抛出该错误)。

    Exception

    同样作为Throwable的子类,既然Error是系统级异常,与之对应的Exception就是应用级异常。这种异常通常都是可能预料到的,由应用抛出该类异常,执行方法时再捕获该类异常。

    Exception的直接子类有很多,大概有数十个,我们将它的所有子类分为两类:

    • 运行时异常
      1,运行时异常(RuntimeException)是那些可能在 Java 虚拟机正常运行期间抛出的异常的超类。程序编译时是不知道到底会不会触发该异常的,只有程序运行起来才知道。它的子类也有很多,例如有空指针异常(NullPointerException), 对象强制转换异常(ClassCastException)等等。
      2,因为运行时异常的不确定性,所以对于程序中抛出的RuntimeException及其子类在程序执行方法期间是不需要我们强制捕获处理它的。
      3,RuntimeException跟Error性质上差不多,都是在程序运行期间可能会产生的异常。但是Error是系统级的异常大都是JVM相关的异常,而RuntimeException则是应用程序级别的异常。

    • 其他应用异常
      1,其他应用异常就是Exception的所有子类里除了RuntimeException外的异常,这些异常都是在执行之前可预见的异常。例如IOException、SQLException等以及用户自定义的Exception异常。
      2,这些异常与RuntimeException不同的是编译器强制要求必须捕获处理他们,即如果程序某处抛出了异常,那么在执行方法前一定要先捕获异常。

    捕获异常

    try{
        // 可能会抛出异常的代码
    }catch(Exception e){
        // 捕获异常的位置
    }finally{
        // 无论有没有抛出异常都会执行的代码
    }
    
    1. try代码块中的语句一旦抛出异常后面未执行的代码将不会在执行,直接跳转到catch中。

    2. 捕获对应异常catch可以有很多个,JVM会从第一个找起。尽量把子异常放在前面,如果你抛出的异常在它的父类后面就直接进到父类异常里了。

    3. 代码块finally也会有不执行的时候,如JVM 过早终止(调用 System.exit(int));在 finally 块中抛出一个未处理的异常;计算机断电、失火、或遭遇病毒攻击。

    相关文章

      网友评论

        本文标题:Java的异常处理机制

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