`

深入java虚拟机 异常,异常表, finally

阅读更多

每个异常表入口包含四个信息:

 

 

 

下面一个小例子:

  

public class GreetDemo {

    public static void main (String[] args) {
        GreetDemo gd = new GreetDemo();
        gd.testException();
    }

    public void testException () {
        try {
            System.out.println("hi");
            int m = 1/0;
        } catch (NullPointerException e) {
            throw e;
        } catch (ArithmeticException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

  testException方法的 字节码:

 

 

testException方法的异常表:

 

有上面的异常表可以知道,异常表中包含三个异常:NullPointerException , ArithmeticException, Exception

NullPointerException 捕捉的范围为上面bytecode的#0至#12 处理该异常从#15开始

ArithmeticException 捕捉的范围为上面bytecode的#0至#12 处理该异常从#18开始

ArithmeticException 捕捉的范围为上面bytecode的#0至#12 处理该异常从#26开始

 

分析一下上面bytecode

首先看一下常量池

由于上面的bytecode中只出现了常量池入口5,6,7,10,12,所以只展示这些常量池入口:

 

 

 

getstatic #5 <java/lang/System/out Ljava/io/PrintStream;>  //获取静态变量
ldc #6 <hi> //从常量池获取常量"hi"并压入栈
invokevirtual #7 <java/io/PrintStream/println(Ljava/lang/String;)V> //调用动态方法
iconst_1 //把int类型的常量1压入栈
iconst_0 //把int类型的常量1压入栈
idiv //对栈顶的两个int类型进行处罚
istore_1 //从栈顶弹出int类型的值,并赋值给位置为1的局部变量
goto 19 //跳转的方法末,return, 退出此方法(方法正常结束)
astore_1 //进入catch分支,把栈顶对象引用弹出,赋值给位置为1局部变量
aload_1  //把位置为1的对象引用进栈
athrow  //弹出栈中异常引用,抛出异常
astore_1 //进入catch分支,把栈顶对象引用弹出,赋值给位置为1局部变量
aload_1  //把位置为1的对象引用进栈
invokevirtual #10 <java/lang/ArithmeticException/printStackTrace()V> //调用异常的printStackTrace方法
goto 19 //跳转的方法末,return, 退出此方法
astore_1
aload_1
invokevirtual #12 <java/lang/Exception/printStackTrace()V>
return //退出方法
 

   每个异常方法都和异常表相关联, 该异常表与方法的字节码序列一起送到class文件中

   如果在方法执行的时候抛出异常,java虚拟机将会在整个异常表中搜索相匹配的项, 如果当前程序计数器在异常表的入口所指定的范围内, 而且所抛出的异常是该入口所指向的类(或为指定类的之类),那么该入口即为所询入口,当遇到第一个匹配项时, 虚拟机将程序计数器设为新的pc指针偏移量位置, 然后从该位置执行, 如果没有发现匹配项, 虚拟机从当前栈中弹出, 再次抛出同样的异常;当虚拟机弹出当前栈桢时,虚拟机马上停止执行当前方法,并且返回至调用本方法的方法, 但是并不继续执行该方法, 而是再该方法抛出同样的异常, 这就是虚拟机在该方法中执行同样的搜索异常表的操作

 

   finally 关键字:

   finally的执行大家都知道,在字节码中如何反应的呢?

   下面是一个小例子:

   

    public void testException () {
        try {
            System.out.println("hi");
            int m = 1/0;
        } catch (NullPointerException e) {
            throw e;
        } catch (ArithmeticException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            System.out.println("fuck you");
        }

        System.out.println("after fuck you, i want say hello");
    }

   testException方法的字节码为:

  

 

 

   该方法的异常表为:

  

 

 由上面的bytecode和异常表可以知道:

 1 上面的bytecode存在重复的部分, #12至#17, #31至#36, #47至#52, #59至#64 这四个区域是重复的部分;他们是代码块finally语句块编译的部分

 2 根据异常表可以知道每个异常捕捉到以后执行的行数;结合上面的bytecode可以知道,每个异常的bytecode执行之后就是finally语句块的bytecode;正常结束以后也是finally语句块的bytecode

 3 结合以上两点可知,finally语句的字节码在任何可能执行到它的地方都加上了(正常结束,三个异常后面,都跟有finally语句的字节码)

  • 大小: 75.6 KB
  • 大小: 12.9 KB
  • 大小: 17.4 KB
  • 大小: 25.4 KB
  • 大小: 24.1 KB
  • 大小: 4.2 KB
  • 大小: 18.3 KB
分享到:
评论

相关推荐

    深入Java虚拟机(原书第2版).pdf【附光盘内容】

    《深入Java虚拟机(原书第2版)》,原书名《Inside the Java Virtual Machine,Second Edition》,作者:【美】Bill Venners,翻译:曹晓钢、蒋靖,出版社:机械工业出版社,ISBN:7111128052,出版日期:2003 年 9 ...

    深入JAVA虚拟机第二版.pdf 目录

    第5章 Java虚拟机 第6章 Java class文件 第7章 类型的生命周期 第8章 连接模型 第9章 垃圾收集 第10章 栈和局部变量操作 第11章 类型转换 第12章 整数运算 第13章 逻辑运算 第14章 浮点运算 第15章 对象和数组 第16...

    深入Java虚拟机(原书第2版)及书中源代码

    第5章 Java虚拟机 第6章 Java class文件 第7章 类型的生命周期 第8章 连接模型 第9章 垃圾收集 第10章 栈和局部变量操作 第11章 类型转换 第12章 整数运算 第13章 逻辑运算 第14章 浮点运算 第15章 对象和数组 第16...

    深入Java虚拟机

    1.3.1 Java虚拟机 1.3.2 类装载器的体系结构 1.3.3 Java class文件 1.3.4 Java API 1.3.5 Java程序设计语言 1.4 Java体系结构的代价 1.5 结论 1.6 资源页 第2章 平台无关 2.1 为什么要平台...

    深入java虚拟机第二版

    深入java虚拟机第二版 第1章 Java体系结构介绍 1.1 为什么使用Java 1.2 网络带来的挑战和机遇 1.3 体系结构 1.3.1 Java虚拟机 1.3.2 类装载器的体系结构 1.3.3 Java class文件 1.3.4 Java API 1.3.5 ...

    深入java虚拟机中文第2版

    本书共分20章,第1-4章解释了Java虚拟机的体系结构,包括Java栈、堆、方法区、执行引擎等;第5-20章深入描述了Java技术的内部细节,包括垃圾收集、Java安全模型、Java的连接模型和动态扩展机制、class文件、运算及...

    深入JAVA虚拟机(第2版)

    1.3.1 Java虚拟机 1.3.2 类装载器的体系结构 1.3.3 Java class文件 1.3.4 Java API 1.3.5 Java程序设计语言 1.4 Java体系结构的代价 1.5 结论 1.6 资源页 第2章 平台无关 2.1 为什么要平台...

    深入java虚拟机

    第5章 Java虚拟机 第6章 Java class文件 第7章 类型的生命周期 第8章 连接模型 第9章 垃圾收集 第10章 栈和局部变量操作 第11章 类型转换 第12章 整数运算 第13章 逻辑运算 第14章 浮点运算 第15章 对象和数组 第16...

    Java面试题合集最新版2024.zip

    Java面试通常涵盖多个方面,包括Java基础知识、编程技能、问题解决能力,以及对Java生态系统和相关...JVM与性能调优:对Java虚拟机(JVM)有一定了解,包括内存管理、垃圾回收等方面,并知道如何进行基本的性能调优。

    疯狂JAVA讲义

    学生提问:不是说JVM是运行Java程序的虚拟机吗?那JRE和JVM的关系是怎样的呢? 8 学生提问:为什么不安装公共JRE系统呢? 9 1.4.2 设置PATH环境变量 10 学生提问:为什么选择设置用户变量,用户变量和系统变量有...

    JAVA入门1.2.3:一个老鸟的JAVA学习心得 PART1(共3个)

    1.5.4 Java虚拟机(Java Virtual Machine) 17 1.5.5 HelloWorld的整个流程 17 1.6 小结:我们学会了编译和运行一个Java程序! 18 1.7 习题 19 第2章 搭建自己的集成开发环境 20 教学视频:31分钟 2.1 安装...

    Java入门1·2·3:一个老鸟的Java学习心得.PART3(共3个)

    1.5.4 Java虚拟机(Java Virtual Machine) 17 1.5.5 HelloWorld的整个流程 17 1.6 小结:我们学会了编译和运行一个Java程序! 18 1.7 习题 19 第2章 搭建自己的集成开发环境 20 教学视频:31分钟 2.1 安装...

Global site tag (gtag.js) - Google Analytics