通过字节码分析this关键字以及异常表的重要作用
在之前的字节码分析中缺少对异常的介绍,这次主要来对字节码异常表相关的东东进行一个学习,下面先来编写一个相关异常的小程序:
接着编译来看用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关键字以及异常表的重要作用相关推荐
- 从字节码看 finally关键字、异常表
大家好,我是烤鸭: 今天说下 finally 这个关键字. 1. 认识finally finally 总是跟 try.catch一起出现,finally是执行方法结束一定要执行的代码,比如流关闭等等 ...
- python把桢写入txt_Java 字节码与字节码分析
1.1 Java 字节码简介Java 字节码由单字节(byte)的指令组成,理论上最多支持 256 个操作码(opcode).实际上 Java 只使用了200左右的操作码, 还有一些操作码则保留给调试 ...
- java中类的字节码_Java 字节码与字节码分析
1.1 Java 字节码简介Java 字节码由单字节(byte)的指令组成,理论上最多支持 256 个操作码(opcode).实际上 Java 只使用了200左右的操作码, 还有一些操作码则保留给调试 ...
- jieba tfidf_【NLP】【三】jieba源码分析之关键字提取(TF-IDF/TextRank)
[一]综述 利用jieba进行关键字提取时,有两种接口.一个基于TF-IDF算法,一个基于TextRank算法.TF-IDF算法,完全基于词频统计来计算词的权重,然后排序,在返回TopK个词作为关键字 ...
- Android Kotlin 学习总结(一) 《KAE 优缺点并且深入字节码分析工作原理》
本章会分为以下内容: 1.Kotlin KAE介绍,使用和原始Android findViewById对比优缺点 2.Kotlin KAE所存在的问题 3.通过字节码分析他的实现原理 阅读本章内容大概 ...
- 字节码分析finally块对return返回值的影响
直接进入主题.看如下代码: public int test(){int i=0;try {i=1;return i;} catch (Exception e) {i=2;return i;}final ...
- java 字节码分析_Java 字节码实践 - 解读
最近刚看完 深入理解 Java 虚拟机 一书中的第 6 章 (类文件结构),便迫不及待地自己写一个小的 Demo,来自己分析一把 Java 源文件经过编译之后成为字节码文件到底是个什么东西?先由一个简 ...
- 透过字节码分析java基本类型数组的内存分配方式。
我们知道java中new方式创建的对象都是在堆中创建的,而局部变量对应的值存放在栈上.那么java中的int [] arr={1,2,3}是存放在什么地方的呢,int []arr = new int[ ...
- 中关村2019逆向 Reverse lebel:控制流平坦化 / python字节码分析
flat 题目名字,流程图都指向了控制流平坦化 通过阅读 https://blog.csdn.net/yangbostar/article/details/6204724 了解了 顺序流/条件流/循环 ...
- AOP: 切面编程框架:AspectJ (三)字节码分析
1:Android AspectJ 插件集成 1.1:AspectJ版本和 Gradle以及Gradle Tools 版本对应关系 GitHub - HujiangTechnology/gradle_ ...
最新文章
- 字符数组、字节数组、字符串转换
- shell函数与数组(了解函数,递归函数运用,了解数组,创建基数和偶数数组,冒泡排序,调试命令)
- linux中tree命令
- mysql普通索引自增_mysql中联合索引中的自增列的增长策略
- 业务活动监视器(BAM)2.0带来的革命
- 【BZOJ 4169】 4169: Lmc的游戏 (树形DP)
- 神经网络算法学习---mini-batch++++mini-batch和batch的区别
- 图的存储结构之十字链表、邻接多重表、边集数组
- Atitit.实现反向代理(1)----url rewrite 配置and内容改写 and -绝对路径链接改写 java php
- DRAM知识整理系列(三):部分时序参数整理
- qq空间已删信息服务器,qq空间恢复已删除的说说方法
- JS请求服务器gbk文件乱码问题
- android 定时截图,这款 APP 让我每天都忍不住想发截图!
- utl raw mysql_oracle中utl_raw
- win10电脑用蓝牙实现文件传输,安卓手机通过蓝牙将文件传送到电脑
- 浏览器访问一个页面的步骤详解
- 学编程和乐高机器人的区别
- 经典物理学电荷连续性方程推导
- 唐澳华的亚索有错吗?
- cookie模拟登陆爬取药智网中药材数据库数据
热门文章
- 一个简单的爬虫例子-天气
- PaddleOCR 识别器数据增强
- 十分钟玩转3D绘图:WxGL完全手册(第二版)
- python控制excel打印_python对excel表格的操作
- gmap 支持python吗_Python:地图上的标记标签使用gmap.marker_层使用hover_-tex选项不工作...
- 计算机如何执行(运行)程序
- Linux之软件包安装——06
- Source Insight 4.0.0084 Patched
- 45个免费LOGO在线制作网站
- python暂停命令_命令行-Python中的暂停