美文网首页
关于异常

关于异常

作者: lionel880 | 来源:发表于2017-12-15 15:34 被阅读0次

参考资料:JVM如何处理异常深入详解

一、Java 异常的概念和分类

所有的异常都派生于Throwable类的一个实例


无标题.jpg

Error

java 运行时的系统错误和资源耗尽错误。 应用程序是不应该跑出这种类型的对象。一般出现错误,也没什么办法

Exception

RunTimeException和其他Exception(主要是IO Exception)

RunTimeException:为程序的逻辑错误
如:类型错误,数组越界,空指针
其他Exception(主要是IO Exception):程序本身没问题,但由于像I/O这样的错误导致异常
如:打开一个不存在的文件,根据字符串找class炸不到等

unchecked 和checked

java将error和RunTimeException归为unchecked 异常,其他为checked 异常

原则上checked 异常要进行声明,而unchecked 异常要么控制不了,如error,要么应该避免发生RunTimeException,不需要捕获

二、JVM如何处理异常

异常表 Exception Table

  • 异常表的构成
    from 可能发生异常的起始点
    to 可能发生异常的结束点
    target 上述from和to之前发生异常后的异常处理者的位置
    type 异常处理者处理的异常的类信息

  • 异常表的调用
    1.JVM会在当前出现异常的方法中,查找异常表,是否有合适的处理者来处理
    2.如果当前方法异常表不为空,并且异常符合处理者的from和to节点,并且type也匹配,则JVM调用位于target的调用者来处理。
    3.如果上一条未找到合理的处理者,则继续查找异常表中的剩余条目
    4.如果当前方法的异常表无法处理,则向上查找(弹栈处理)刚刚调用该方法的调用处,并重复上面的操作。
    5.如果所有的栈帧被弹出,仍然没有处理,则抛给当前的Thread,Thread则会终止。
    6.如果当前Thread为最后一个非守护线程,且未处理异常,则会导致JVM终止运行。

  • catch的顺序
    catch的顺序决定了异常处理者在异常表的位置
    因为我们实际中可以catch很多的exception 类型,所以越具体的exception要放在前面,宽泛的exception或者throwable一般都用于兜底

  • finally的执行
    finally是如何真正执行的,当前编译器的做法是复制finnal 代码块的内容,分别放在try-catch代码块的所有正常执行路径和异常执行路径的出口中

public static void XiaoXiao() {
   try {
       dada();
   } catch (Exception e) {
       e.printStackTrace();
   } finally {
       System.out.println("Finally");
   }
}
//通过javap 反编译
public static void XiaoXiao();
    Code:
       0: invokestatic  #3                  // Method dada:()V
       3: getstatic     #6                  // Field java/lang/System.out:Ljava/io/PrintStream;
       6: ldc           #7                  // String Finally
       8: invokevirtual #8                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
      11: goto          41
      14: astore_0
      15: aload_0
      16: invokevirtual #5                  // Method java/lang/Exception.printStackTrace:()V
      19: getstatic     #6                  // Field java/lang/System.out:Ljava/io/PrintStream;
      22: ldc           #7                  // String Finally
      24: invokevirtual #8                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
      27: goto          41
      30: astore_1
      31: getstatic     #6                  // Field java/lang/System.out:Ljava/io/PrintStream;
      34: ldc           #7                  // String Finally
      36: invokevirtual #8                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
      39: aload_1
      40: athrow
      41: return
    Exception table:
       from    to  target type
           0     3    14   Class java/lang/Exception
           0     3    30   any
          14    19    30   any

这三份finally代码块都放在什么位置:
第一份位于try代码后 : 若果try中代码正常执行,没有异常那么finally代码就在这里执行。
第二份位于catch代码后 : 如果try中有异常同时被catch捕获,那么finally代码就在这里执行。
第三份位于异常执行路径 : 如果如果try中有异常但没有被catch捕获,或者catch又抛异常,那么就执行最终的finally代码

  • return 和 finally
    这个其实不必要强记,只需要你知道java编译器的原理就可以了,java编译器将finally编译进去后,如果有return是先执行finnal在执行return的
invokestatic #3   // Method testNPE:()V
 3: ldc  #6   // String OK
 5: astore_0
 6: getstatic #7   // Field java/lang/System.out:Ljava/io/PrintStream;
 9: ldc  #8   // String tryCatchReturn
 11: invokevirtual #9   // Method java/io/PrintStream.println:(Ljava/lang/String;)V
 14: aload_0
 15: areturn 返回OK字符串,areturn意思为return a reference from a method

三、未捕获异常是如何处理的

当一个线程遇到的异常,并没有被正确的捕获,就成为了未捕获异常,如没有catch或catch没有兜底的exception和throwable

  • 如何设置未捕获异常


    image.png
  • 线程发生uncaughtException,JVM怎么处理
    1.每个线程有一个变量uncaughtExceptionHandler来保存未捕获异常的handle
    2.线程分发目标的handle,优先分发给当前线程的uncaughtExceptionHandler
    3.上述为null时,分发给自己所在的ThreadGroup来作为未捕获异常处理者,ThreadGroup implements Thread.UncaughtExceptionHandler
    4.ThreadGroup会尝试转给它的父ThreadGroup(如果存在的话)
    5.如果上面没有找到对应的ThreadGroup,则尝试获取Thread.getDefaultUncaughtExceptionHandler()并分发

相关文章

  • 关于异常

    异常包括检测异常和非检测异常,开发人员在使用的时候通常使用非检测异常,认为检测异常没有什么用,实际上这种思想是错误...

  • 关于异常

    参考资料:JVM如何处理异常深入详解 一、Java 异常的概念和分类 所有的异常都派生于Throwable类的一个...

  • 关于异常

    异常一般是指运行期(此处特指Exception类)会发生的导致程序意外中止的问题,是一种对问题的描述后的封装对象。...

  • Objective-C - 异常处理(NSException)

    苹果关于异常的详细文档关于自定义异常或者扩展:Objective-C中处理异常是依赖于NSException实现的...

  • 阿里Java规范-02-异常日志

    =================(一)异常处理==================关于接口使用抛异常还是返回错误...

  • 关于异常处理

    首先是报错的时候对于异常的认知,多写多出错增长经验吧 python报错中英文对照-http://www.runoo...

  • 关于异常处理

    一、为什么要有异常机制? 1、在传统语言C语言中,当你操作资源时,一般是通过函数返回值code来判断是否执行成功(...

  • 关于异常类型

    1. {id}输入参数的异常 2. name=Francis请求参数的异常 3. Raw data:JSON请求体的异常

  • RxJava处理业务异常的几种方式

    关于异常 Java的异常可以分为两种:运行时异常和检查性异常。 运行时异常:RuntimeException类及其...

  • 1. 模块做异常测试考虑点

    ###关于异常测试### 异常测试就是人为地构造异常场景,观察服务在异常场景下的表现是否符合预期。 常见异常测试类...

网友评论

      本文标题:关于异常

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