在之前的字节码分析中缺少对异常的介绍,这次主要来对字节码异常表相关的东东进行一个学习,下面先来编写一个相关异常的小程序:

接着编译来看用javap -verbose来查看一下它的字节码信息:

xiongweideMacBook-Pro:classes xiongwei$ javap -verbose com/jvm/bytecode/MyTest3.class
Classfile /Users/xiongwei/Documents/workspace/IntelliJSpace/jvm_lectue/out/production/classes/com/jvm/bytecode/MyTest3.classLast modified Sep 26, 2018; size 1056 bytesMD5 checksum 67ac394f07ca1303eb0119b94486d428Compiled from "MyTest3.java"
public class com.jvm.bytecode.MyTest3minor version: 0major version: 52flags: ACC_PUBLIC, ACC_SUPER
Constant pool:#1 = Methodref          #15.#35        // java/lang/Object."<init>":()V#2 = Class              #36            // java/io/FileInputStream#3 = String             #37            // test.txt#4 = Methodref          #2.#38         // java/io/FileInputStream."<init>":(Ljava/lang/String;)V#5 = Class              #39            // java/net/ServerSocket#6 = Methodref          #5.#40         // java/net/ServerSocket."<init>":(I)V#7 = Methodref          #5.#41         // java/net/ServerSocket.accept:()Ljava/net/Socket;#8 = Fieldref           #42.#43        // java/lang/System.out:Ljava/io/PrintStream;#9 = String             #44            // finally#10 = Methodref          #45.#46        // java/io/PrintStream.println:(Ljava/lang/String;)V#11 = Class              #47            // java/io/FileNotFoundException#12 = Class              #48            // java/io/IOException#13 = Class              #49            // java/lang/Exception#14 = Class              #50            // com/jvm/bytecode/MyTest3#15 = Class              #51            // java/lang/Object#16 = Utf8               <init>#17 = Utf8               ()V#18 = Utf8               Code#19 = Utf8               LineNumberTable#20 = Utf8               LocalVariableTable#21 = Utf8               this#22 = Utf8               Lcom/jvm/bytecode/MyTest3;#23 = Utf8               test#24 = Utf8               is#25 = Utf8               Ljava/io/InputStream;#26 = Utf8               serverSocket#27 = Utf8               Ljava/net/ServerSocket;#28 = Utf8               StackMapTable#29 = Class              #47            // java/io/FileNotFoundException#30 = Class              #48            // java/io/IOException#31 = Class              #49            // java/lang/Exception#32 = Class              #52            // java/lang/Throwable#33 = Utf8               SourceFile#34 = Utf8               MyTest3.java#35 = NameAndType        #16:#17        // "<init>":()V#36 = Utf8               java/io/FileInputStream#37 = Utf8               test.txt#38 = NameAndType        #16:#53        // "<init>":(Ljava/lang/String;)V#39 = Utf8               java/net/ServerSocket#40 = NameAndType        #16:#54        // "<init>":(I)V#41 = NameAndType        #55:#56        // accept:()Ljava/net/Socket;#42 = Class              #57            // java/lang/System#43 = NameAndType        #58:#59        // out:Ljava/io/PrintStream;#44 = Utf8               finally#45 = Class              #60            // java/io/PrintStream#46 = NameAndType        #61:#53        // println:(Ljava/lang/String;)V#47 = Utf8               java/io/FileNotFoundException#48 = Utf8               java/io/IOException#49 = Utf8               java/lang/Exception#50 = Utf8               com/jvm/bytecode/MyTest3#51 = Utf8               java/lang/Object#52 = Utf8               java/lang/Throwable#53 = Utf8               (Ljava/lang/String;)V#54 = Utf8               (I)V#55 = Utf8               accept#56 = Utf8               ()Ljava/net/Socket;#57 = Utf8               java/lang/System#58 = Utf8               out#59 = Utf8               Ljava/io/PrintStream;#60 = Utf8               java/io/PrintStream#61 = Utf8               println
{public com.jvm.bytecode.MyTest3();descriptor: ()Vflags: ACC_PUBLICCode:stack=1, locals=1, args_size=10: aload_01: invokespecial #1                  // Method java/lang/Object."<init>":()V4: returnLineNumberTable:line 9: 0LocalVariableTable:Start  Length  Slot  Name   Signature0       5     0  this   Lcom/jvm/bytecode/MyTest3;public void test();descriptor: ()Vflags: ACC_PUBLICCode:stack=3, locals=4, args_size=10: new           #2                  // class java/io/FileInputStream3: dup4: ldc           #3                  // String test.txt6: invokespecial #4                  // Method java/io/FileInputStream."<init>":(Ljava/lang/String;)V9: astore_110: new           #5                  // class java/net/ServerSocket13: dup14: sipush        999917: invokespecial #6                  // Method java/net/ServerSocket."<init>":(I)V20: astore_221: aload_222: invokevirtual #7                  // Method java/net/ServerSocket.accept:()Ljava/net/Socket;25: pop26: getstatic     #8                  // Field java/lang/System.out:Ljava/io/PrintStream;29: ldc           #9                  // String finally31: invokevirtual #10                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V34: goto          8437: astore_138: getstatic     #8                  // Field java/lang/System.out:Ljava/io/PrintStream;41: ldc           #9                  // String finally43: invokevirtual #10                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V46: goto          8449: astore_150: getstatic     #8                  // Field java/lang/System.out:Ljava/io/PrintStream;53: ldc           #9                  // String finally55: invokevirtual #10                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V58: goto          8461: astore_162: getstatic     #8                  // Field java/lang/System.out:Ljava/io/PrintStream;65: ldc           #9                  // String finally67: invokevirtual #10                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V70: goto          8473: astore_374: getstatic     #8                  // Field java/lang/System.out:Ljava/io/PrintStream;77: ldc           #9                  // String finally79: invokevirtual #10                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V82: aload_383: athrow84: returnException table:from    to  target type0    26    37   Class java/io/FileNotFoundException0    26    49   Class java/io/IOException0    26    61   Class java/lang/Exception0    26    73   anyLineNumberTable:line 13: 0line 14: 10line 15: 21line 23: 26line 24: 34line 16: 37line 23: 38line 24: 46line 18: 49line 23: 50line 24: 58line 20: 61line 23: 62line 24: 70line 23: 73line 24: 82line 25: 84LocalVariableTable:Start  Length  Slot  Name   Signature10      16     1    is   Ljava/io/InputStream;21       5     2 serverSocket   Ljava/net/ServerSocket;0      85     0  this   Lcom/jvm/bytecode/MyTest3;StackMapTable: number_of_entries = 5frame_type = 101 /* same_locals_1_stack_item */stack = [ class java/io/FileNotFoundException ]frame_type = 75 /* same_locals_1_stack_item */stack = [ class java/io/IOException ]frame_type = 75 /* same_locals_1_stack_item */stack = [ class java/lang/Exception ]frame_type = 75 /* same_locals_1_stack_item */stack = [ class java/lang/Throwable ]frame_type = 10 /* same */
}
SourceFile: "MyTest3.java"

其中重点观注一下test()方法的信息:

其中stack表示这个方法运行的任何时刻所能达到的操作数栈的最大深度;local表示方法执行期间创建的局部变量的数目,包含用来表示传入的参数的局部变量。args_size表示方法的参数的总个数。
下面首先来解释一下为啥args_size等于1,很明显咱们这个方法是一个无参的定义,关于这个在之前的学习中已经解释过了,这里再巩固一下:对于Java类中的每一个实例方法(非static方法),其在编译后所生成的字节码当中,方法参数的数量总是会比源代码中方法的参数的数量多一个(this),它位于方法的第一个参数位置处;这样,我们就可以在Java的实例方法中使用this来去访问当前对象的属性以及其它方法。这个操作是在编译期间完成的,既由javac编译器在编译的时候将对this的访问转化为对一个普通实例方法参数的访问,接下来的运行期间,由JVM在调用实例方法时,自动向实例方法传入该this参数。所以,在实例方法的局部变量表中,至少会有一个指向当前对象的局部变量【也就是会存在于下面要分析的locals中】

接着来看一下locals,为啥有4个局部变量呢?下面来分析一下:
1、当然就是隐含的this啦,上面分析stack中标明处有说明。

2、当然就是is喽,如下:

3、当然就是serverSocket喽:

4、那它倒底是啥呢?貌似咱们能见到局部变量就木有了,其实这个局部变量是位于catch当中的,如下:

也就是如果抛出了异常,那么最终这三个异常就会产生一个局部变量,如果不抛出异常,那么这个最多4个局部变量中最终只会使用3个局部变量。

最后再来看一下statck=3,也就是这个方法最多能往栈中压入3个元素,关于栈在之后还会详述的,这里有个基本印象。

接着来则到了该篇要讨论的核心话题:异常,对应方法的code属性中exception_table,这里存放的是处理异常的信息。每一个exception_table表项由start_pc、end_pc、handler_pc、catch_type组成,那这四个元素分别代表啥呢?下面来看一下:

  • start_pc和end_pc表示在code数组中的从start_pc到end_pc处(包含start_pc,不包含end_pc)的指令抛出的异常会由这个表项来处理。
  • handler_pc表示处理异常的代码的开始处。catch_type表示会被处理的异常类型,它指向常量池里的一个异常表。当catch_type为0时,表示处理所有的异常。

其实异常在字节码中是存在有goto语句的,也就是当发生异常则会goto到指定的位置进行异常处理,大至看一下:

具体异常相关的分析下次再继续。

通过字节码分析this关键字以及异常表的重要作用相关推荐

  1. 从字节码看 finally关键字、异常表

    大家好,我是烤鸭: 今天说下 finally 这个关键字. 1.  认识finally finally 总是跟 try.catch一起出现,finally是执行方法结束一定要执行的代码,比如流关闭等等 ...

  2. python把桢写入txt_Java 字节码与字节码分析

    1.1 Java 字节码简介Java 字节码由单字节(byte)的指令组成,理论上最多支持 256 个操作码(opcode).实际上 Java 只使用了200左右的操作码, 还有一些操作码则保留给调试 ...

  3. java中类的字节码_Java 字节码与字节码分析

    1.1 Java 字节码简介Java 字节码由单字节(byte)的指令组成,理论上最多支持 256 个操作码(opcode).实际上 Java 只使用了200左右的操作码, 还有一些操作码则保留给调试 ...

  4. jieba tfidf_【NLP】【三】jieba源码分析之关键字提取(TF-IDF/TextRank)

    [一]综述 利用jieba进行关键字提取时,有两种接口.一个基于TF-IDF算法,一个基于TextRank算法.TF-IDF算法,完全基于词频统计来计算词的权重,然后排序,在返回TopK个词作为关键字 ...

  5. Android Kotlin 学习总结(一) 《KAE 优缺点并且深入字节码分析工作原理》

    本章会分为以下内容: 1.Kotlin KAE介绍,使用和原始Android findViewById对比优缺点 2.Kotlin KAE所存在的问题 3.通过字节码分析他的实现原理 阅读本章内容大概 ...

  6. 字节码分析finally块对return返回值的影响

    直接进入主题.看如下代码: public int test(){int i=0;try {i=1;return i;} catch (Exception e) {i=2;return i;}final ...

  7. java 字节码分析_Java 字节码实践 - 解读

    最近刚看完 深入理解 Java 虚拟机 一书中的第 6 章 (类文件结构),便迫不及待地自己写一个小的 Demo,来自己分析一把 Java 源文件经过编译之后成为字节码文件到底是个什么东西?先由一个简 ...

  8. 透过字节码分析java基本类型数组的内存分配方式。

    我们知道java中new方式创建的对象都是在堆中创建的,而局部变量对应的值存放在栈上.那么java中的int [] arr={1,2,3}是存放在什么地方的呢,int []arr = new int[ ...

  9. 中关村2019逆向 Reverse lebel:控制流平坦化 / python字节码分析

    flat 题目名字,流程图都指向了控制流平坦化 通过阅读 https://blog.csdn.net/yangbostar/article/details/6204724 了解了 顺序流/条件流/循环 ...

  10. AOP: 切面编程框架:AspectJ (三)字节码分析

    1:Android AspectJ 插件集成 1.1:AspectJ版本和 Gradle以及Gradle Tools 版本对应关系 GitHub - HujiangTechnology/gradle_ ...

最新文章

  1. 字符数组、字节数组、字符串转换
  2. shell函数与数组(了解函数,递归函数运用,了解数组,创建基数和偶数数组,冒泡排序,调试命令)
  3. linux中tree命令
  4. mysql普通索引自增_mysql中联合索引中的自增列的增长策略
  5. 业务活动监视器(BAM)2.0带来的革命
  6. 【BZOJ 4169】 4169: Lmc的游戏 (树形DP)
  7. 神经网络算法学习---mini-batch++++mini-batch和batch的区别
  8. 图的存储结构之十字链表、邻接多重表、边集数组
  9. Atitit.实现反向代理(1)----url rewrite 配置and内容改写 and -绝对路径链接改写 java php
  10. DRAM知识整理系列(三):部分时序参数整理
  11. qq空间已删信息服务器,qq空间恢复已删除的说说方法
  12. JS请求服务器gbk文件乱码问题
  13. android 定时截图,这款 APP 让我每天都忍不住想发截图!
  14. utl raw mysql_oracle中utl_raw
  15. win10电脑用蓝牙实现文件传输,安卓手机通过蓝牙将文件传送到电脑
  16. 浏览器访问一个页面的步骤详解
  17. 学编程和乐高机器人的区别
  18. 经典物理学电荷连续性方程推导
  19. 唐澳华的亚索有错吗?
  20. cookie模拟登陆爬取药智网中药材数据库数据

热门文章

  1. 一个简单的爬虫例子-天气
  2. PaddleOCR 识别器数据增强
  3. 十分钟玩转3D绘图:WxGL完全手册(第二版)
  4. python控制excel打印_python对excel表格的操作
  5. gmap 支持python吗_Python:地图上的标记标签使用gmap.marker_层使用hover_-tex选项不工作...
  6. 计算机如何执行(运行)程序
  7. Linux之软件包安装——06
  8. Source Insight 4.0.0084 Patched
  9. 45个免费LOGO在线制作网站
  10. python暂停命令_命令行-Python中的暂停