异常处理的两大组成要素:抛出异常和捕获异常。这两大要素共同实现程序控制流的非正常转移。

抛出异常分为:显式和隐式两种。

显式抛异常的主题是应用程序,它指的是在程序中使用 “throw”  关键字。手动将异常实例抛出。

隐式抛异常的主题是java虚拟机,它指的是java虚拟机在执行过程中,碰到无法继续执行的异常状态,自动过抛出异常。举例来说,java虚拟机在执行读取数组操作时,发现输入的索引值是负数,故而抛出数组索引越界异常(ArrayIndexOutOfBoundsException)。

捕获异常则涉及了如下三种代码块:

1、try代码块:用来标记需要进行异常监控的代码。

2、catch代码块:跟在try代码块之后,用来捕获在try代码块中触发的某种类型的异常。除了声明所捕获异常的类型之外,catch代码块还定义了针对该异常类型的异常处理器。在java中try代码块后可以跟多个catch代码块,来捕获不同的异常。java虚拟机会从上至下匹配异常处理器。因此,前面的catch代码块所捕获的异常类型不能覆盖后面的,否则编译器会报错。

3、finally代码块:跟在try代码块和catch代码块之后,用来声明一段必定运行的代码。它的设计初衷是为了避免跳过某些关键的清理代码。例如关闭已打开的系统资源。

在程序正常执行的情况下,这段代码会在try代码块执行之后执行。否则,也就是在try代码块抛异常的情况下,如果该异常没有被捕获,finally代码块会直接运行,并且在运行之后重新抛出异常。

如果该异常被catch代码块捕获,finally代码块则在catch代码块之后运行。在某些不幸的情况下,catch代码块也触发了异常,那么finally代码块同样会执行,并会抛出catch代码块触发的异常。在某极端不幸的情况下,finally代码块也触发了异常,那么只好中断当前finally代码块的执行,并往外抛出异常。

异常的基本概念

在java语言规范中所有的异常都是Throwable类或者其子类实例。Throwable类有两大直接的子类。Error和Exception。

Error:涵盖程序不应捕获的异常。当程序触发error是他的执行状态已经无法恢复,需要中止线程甚至是中止虚拟机。

Exception:涵盖程序可能需要捕获并且处理的异常。

Exception 有一个特殊的子类RuntimeException ,用来表示线程虽然无法继续执行但仍可以抢救一下的情况。数组索引越界便是其中的一种。

RuntimeException 和 Error属于java的非检查异常(unchecked exception)。其他异常则属于检查异常(checked exception)。在java语法中所有的检查异常都需要程序显示的捕获,或者在方法声明中用throws关键字标注。通常情况下,程序中自定义的异常为检查异常。以便最大化利用java编译器的编译时检查。

异常实例的构造非常昂贵。这是由于在构造异常实例时,java虚拟机便需要生成该异常的栈轨迹(stack trace)。该操作会逐一访问当前线程的java栈帧,并且记录下各种调试信息,包括栈帧所指向方法的名字,方法所在的类名、文件名,以及在代码中的第几行触发该异常。

JVM的捕获异常机制

在编译生成的字节码中,每个方法都附带一个异常表。异常表中,每一个条目代表一个异常处理器,并且由from指针、to指针和target指针以及所捕获的异常类型构成。这些指针的值是字节码索引(bytecode index,bci)用以定位字节码。其中feom指针和to指针标示了该异常处理器所监控的范围,例如try代码块所覆盖的范围。target指针则指向异常处理器的起始位置,例如catch代码块的起始位置。

当程序触发异常时,JVM会从上至下遍历异常表中的所有条目。当触发异常的字节码的索引值在某个异常表条目的监控范围内,JVM会判断所抛出的异常和该条目想要捕获的异常是否匹配。如果匹配,JVM会将控制流转移至该条目target指针指向的字节码。如果遍历完所有的条目,JVM仍未匹配到异常处理器,那么它会弹出当前方法所对应的java栈帧,并且在调用者(caller)中重复上述操作。在最坏的情况下,JVM需要遍历当前线程java栈上所有方法的异常表。

finally代码块的编译比较复杂。当前版本java编译器的做法,是复制finally代码块的内容,分别放在try-catch代码块所有正常执行路径以及异常执行路径的出口中。针对异常执行路径,java编译器会生成一个或多个异常表条目,监控整个try-catch代码块,并且捕获所有种类的异常。这些异常表条目的target指针将指向将指向另一份复制的finally代码块。并且,在这个finally代码块的最后,java编译器会重新抛出所捕获得异常。

JVM的异常处理的更多相关文章

  1. JVM总结-异常处理

    众所周知,异常处理的两大组成要素是抛出异常和捕获异常.这两大要素共同实现程序控制流的非正常转移. 抛出异常可分为显式和隐式两种.显式抛异常的主体是应用程序,它指的是在程序中使用“throw”关键字,手 ...

  2. JVM 学习(一)反射、垃圾回收、异常处理--- 2019年4月

    1.JVM 基础知识点 JVM 虚拟机包含了:自动内存管理器.垃圾回收(垃圾回收调优). 执行顺序:Java 代码 --- .class 字节码文件(加载到虚拟机中) --- Java 类放在方法区中 ...

  3. 四:JVM调优原理与常见异常处理方案

    在jvm调优之前,我们必须先了解jvm的内存模型与GC回收机制,这些在我前面的文章里面有介绍!接下来我们通过一个案例来调整jvm性能. 一测试案例: 1.1 编写demo import java.te ...

  4. 基本数据类型 异常 数组排序 JVM区域划分

               Day01 1.基本数据类型各占几个字节 Byte 1 short2 int4 long8 float4 double6 char2 boolean1 Byte b1=3,b2= ...

  5. java.lang.Throwable 异常/深入

    有几个现象是需要总结的: -------------------------------------- 在java语言中,错误类的基类是java.lang.Error,异常类的基类是java.lang ...

  6. 黑马程序员_Java面向对象_异常

    6.异常 1.异常: 就是程序在运行时出现不正常的情况.问题也是现实生活中一个具体的事物,也可以通过Java的类进行描述,并封装成对象.Exception和Error的子类名都是以父类名作为后缀名. ...

  7. Java并发学习 & Executor学习 & 异常逃逸 & 同步互斥Best Practice & wait/notify, conditon#await/signal

    看了这篇文章:http://www.ciaoshen.com/2016/10/28/tij4-21/ 有一些Java并发的内容,另外查了一些资料. 朴素的Thread 首先,Java中关于线程Thre ...

  8. Java异常模块

    JAVA异常的捕获与处理 视频链接:https://edu.aliyun.com/lesson_1011_8939#_8939 java语言提供最为强大的支持就在于异常的处理操作上. 1,认识异常对程 ...

  9. 流言粉碎机:JAVA使用 try catch 会严重影响性能

    目录 一.JVM 异常处理逻辑 二.关于JVM的编译优化 1. 分层编译 2. 即时编译器 1. 解释模式 2. 编译模式 3. 提前编译器:jaotc 三.关于测试的约束 执行用时统计 编译器优化的 ...

随机推荐

  1. Common Subsequence 最大公共子序列问题

    Problem Description A subsequence of a given sequence is the given sequence with some elements (poss ...

  2. jQuery Ajax 全解析(转载)

    本文地址: jQuery Ajax 全解析 本文作者:QLeelulu 转载请标明出处! jQuery确实是一个挺好的轻量级的JS框架,能帮助我们快速的开发JS应用,并在一定程度上改变了我们写Java ...

  3. [Android Tips] 32. 解决 Android Device Monitor 在 Mac OS X 卡住

    Alternatively you can keep latest jdk and update swt used by monitor: get updated swt: https://www.e ...

  4. 【JavaScript算法】---快速排序法

    一.快速排序法概念 我们将一个杂乱无章的数组进行一个快速排序,可以先从一个数组中取一个中间值,将一个数组一分为2,左边的数组跟中间值进行比较,小的放在左边,大的放在右边.比较完毕后再次取中间值,再次比 ...

  5. Jenkins中maven的作用--构建项目(三)

    本文主要根据Jenkins上的日志来继续说明构建项目的过程,上文我们已经讲到构建一个测试环境或单独终端的过程,详情可以了解上篇文章 一.背景介绍 首先看下SVN代码的仓库的结构: 代码仓库里有一个文件 ...

  6. RPN网络

    Region Proposal Network RPN的实现方式:在conv5-3的卷积feature map上用一个n*n的sliding window(论文中n=3)生成一个长度为256(ZF网络 ...

  7. python pip源配置

    一.Linux版本: linux的文件存放在:~/.pip/pip.conf 二.windows版本: 在用户文件夹下创建pip目录,并在pip目录下创建pip.ini文件(%HOME%\pip\pi ...

  8. SELINUX导致数据修改权限不成功

    SELINUX导致数据修改权限不成功基本概念参考:https://blog.csdn.net/yanjun821126/article/details/80828908 查看SELinux状态: ./ ...

  9. python 类高级语法 静态方法

    通过@staticmethod装饰器即可把其装饰的方法变为一个静态方法,什么是静态方法呢?其实不难理解,普通的方法,可以在实例化后直接调用,并且在方法里可以通过self.调用实例变量或类变量,但静态方 ...

  10. grep命令做永久别名 显示颜色

    grep命令做永久别名  显示颜色 http://jingyan.baidu.com/article/22fe7ced17c1543002617f9c.htmlhttp://blog.csdn.net ...