Java字节码方法表与属性表详解
继续跟着上一次【https://www.cnblogs.com/webor2006/p/9502507.html】的那10个代表code的字节分析,如下:
而这些字节其实对应的信息是它:
所以问题就来了,aload_0不是助记符信息么,怎么就能够跟字节码文件中的字节对应上呢?所谓助记符其实也就是帮忙我们去记忆的符合,在底层其实也是对应的一个个十六进制的数字的,其它aload_0对应的就是2A这个十六进制数字,凭什么这么说?因为有jclasslib这么好的工具能帮我们对应上,将鼠标放在助记符上发现是一个可以点的链接,如下:
点一下“aload_0”发现居然链到了oracle的官网上的说明上去了,如下:
所以第一个字节已经分析完了,确实是跟助记符对应上了,接着来分析第二个字节:
而在jsclasslib中对应的第二个助记符是“invokespecial”,点击链到官网看一下:
而它的作用可以理解成就是调用父类的方法,很明显对于咱们自定义的子类肯定会去调用父类的构造方法,而这个助记符是有参数的:
其实也就是往后的两个字节就是该助记符所对应的参数,如下:
对应常量池为:
也就是构造方法嘛,如jsclasslib所示:
接下来继续往下走一个字节:
又对应aload_0,如下:
接着再往后看一个字节:
其实它就是对应下一个助记符,如下:
为啥如此任性呢,因为点击查看一下说明就晓了啦:
为啥要push一个1呢?实际就是给咱们定义的成员变量a赋值,如下:
可见,该变量的赋值是在默认构造函数中进行的,而不是直接进行赋值的,这也就是分析字节码文件的好处,可以更加真实的发现底层细节。
接下来再数一个字节:
当然它又对应另一个助记符喽,如下:
点击看一下官网说明:
接下来该助记符是携带有参数的,所以再往后数两个字节:
对应常量池:
也就是给MyTest1的成员变量a赋值为1。
接下来再数一个字节:
对应于如下助记符:
点击确认一下:
至此整个构造方法就已经执行完了。发现通过分析字节码也能获得不少新知识嘛,仅通过这个构造函数的执行流程就能知道了对于我们定义的成员变量原来是在构造方法中进行赋值而非直接赋值的,还是挺有价值的。
好,方法的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时,表示处理所有的异常。
接下来就到属性相关的东东了,如下:
所以往下数2个字节:
说明该方法有两个属性,往下数两个字节则是第一个属性的名字索引,如下:
也就是对应第10的常量池,为:
该属性用来表示code数组中的字节码和Java代码行数之间的关系。这个属性可以用来在调试的时候定位代码执行的行数。而该属性的结构为:
其中attribute_name_index就是常量索引10,接下来数4个字节则是属性的长度attribute_length,如下:
也就是属性的长度为10,也就是接下来10个字节则为LineNumberTable的属性信息,如下:
看一下jclasslib:
下面具体来分析一下这10个字节,根据结构体来看:
先2个字节表示属性表有几对映射,如下:
说明有两对映射,然后再回到结构体中,每对映射的内容为:
每对占4个字节,先看第一对映射:
也就是start_pc=0;line_number=3,对应于jclasslib:
由于咱们源代码木有构造方法,所以字节码对应源代码就在第3行,如下:
接下来看第二对映射:
也就是start_pc=4;line_number=4,对应于jclasslib:
因为成员变量的赋值是在构造方法中完成的,所以对应第4行代码:
好,方法的第一个属性已经完了,接下来以同样的顺序来查看方法的第二个属性信息了,走2个字节来看属性名称索引,如下:
对应第11个常量池索引,如下:
它的结构跟LineNumberTable差不多的,往后数四个字节则是局部变量表所占的长度:
长度为12,如jclasslib所示:
然后往后数12个字节则是局部变量的具体信息,首先两个字节则为局部变量的个数,如下:
呃~~构造方法哪来的局部变量呢,好奇怪,先不管先来把其它字节分析完,再往后四个字节表示start_pc和length,如下:
如jclasslib所示:
接下来则为局部变量的索引为0,也就是第一个局部变量:
再往后两个字节则是局部变量对应常量池的索引,如下:
再接下来两个字节则是对该局部变量的一个描述常量索引,如下:
所以对应jclasslib中可以看到:
那思考一下为啥在构造方法中会有一个this的局部变量呢?我们知道在所有方法中我们都能使用this关键字来访问当前的对象,而从字节层面来讲其实this是作为方法的第一个参数传进来的,也就是说对于Java的一个实例方法而言最少会有一个this的局部变量存在!
还剩最后两个字节则为stackmaptable信息,JDK1.6加入的,主要做校验检查的,因为0嘛所以后面肯定木有相关的信息了,这里就直接忽略,如下:
Java字节码方法表与属性表详解的更多相关文章
- Java字节码(.class文件)格式详解(一)
原文链接:http://www.blogjava.net/DLevin/archive/2011/09/05/358033.html 小介:去年在读<深入解析JVM>的时候写的,记得当时还 ...
- Java线程通讯方法之wait()、nofity() 详解
Java线程通讯方法之wait().nofity() 详解 本文将探讨以下问题: synchronized 代码块使用 notify()与notifyAll()的区别 Java wait(),noti ...
- JVM Java字节码方法表与属性
方法表 1.methods_count method_info,前三个字段和field_info一样 2.方法的属性结构 方法中的每个属性都是一个attribut_info结构 JVM定义了部分at ...
- Java字节码方法表与属性表深度剖析
方法表: 在上一次咱们已经分析到了字段信息了,如下: 紧接着就是方法相关的信息了: 而它展开之后的结构为: 所以往后数2个字节,看一下方法的总数: 3个方法,可咱们只定义了两个方法呀: 因为编译器会为 ...
- Java字节码方法表结构深度剖析
继续上一次[https://www.cnblogs.com/webor2006/p/9459681.html]的字节码分析,这次来分析一下最为复杂的方法表的信息,如下: 而上一次分析到了属性表的位置在 ...
- Java线程阻塞方法sleep()和wait()精炼详解
版权声明:因为个人水平有限,文章中可能会出现错误,如果你觉得有描述不当.代码错误等内容或者有更好的实现方式,欢迎在评论区告诉我,即刻回复!最后,欢迎关注博主!谢谢 https://blog.csdn. ...
- Java字节码操纵框架ASM小试
本文主要内容: ASM是什么 JVM指令 Java字节码文件 ASM编程模型 ASM示例 参考资料汇总 JVM详细指令 ASM是什么 ASM是一个Java字节码操纵框架,它能被用来动态生成类或者增强既 ...
- 从 HelloWorld 看 Java 字节码文件结构
很多时候,我们都是从代码层面去学习如何编程,却很少去看看一个个 Java 代码背后到底是什么.今天就让我们从一个最简单的 Hello World 开始看一看 Java 的类文件结构. 在开始之前,我们 ...
- 空手套白狼,硬阅java字节码class文件
如下,是一些java字节码也就是原始的class文件,当应用部署到线上之后,我们能够看到的也就是这样的字样了.那么怎样解呢?就让我们一起,来解读解读字节码吧! Offset A B C D E F C ...
随机推荐
- Unity与Android刘海屏适配
本周学习Unity与Android刘海屏适配 关于刘海屏适配部分 网上有很多教程 这里只是做一下整理 https://blog.csdn.net/xj1009420846/article/detail ...
- opencv-windows安装教程
一.下载opencv 下载链接: https://opencv.org/releases/ 二.运行exe 运行exe(其实是解压),将压缩包解压到相应目录,如: D:\Program Files ( ...
- mysql的AB及读写和集群
Mysql的AB及读写 第1章 Mysql的AB配置 1.1 master配置 1.2 slave配置 第2章 读写分离 2.1 安装mycat 2.2 启动mycat 2.3 登录mycat相关问 ...
- python set集合(16)
在python变量中除了以前文章所提到的整形int / 浮点数float / 布尔值bool / 列表list / 字典dict 之外,还有一个类型我们还没有做详细介绍,这个变量类型就是集合set. ...
- Python练手项目:20行爬取全王者全英雄皮肤
引言 王者荣耀大家都玩过吧,没玩过的也应该听说过,作为时下最火的手机MOBA游戏,咳咳,好像跑题了.我们今天的重点是爬取王者荣耀所有英雄的所有皮肤,而且仅仅使用20行Python代码即可完成. ...
- RocketMQ之三:RocketMQ集群环境搭建
1.初步理解Producer/Consumer Group 在安装RocketMQ之前我们先来理解Group概念,在RocketMQ中Group是很重要的.通过Group机制,让RocketMQ天然的 ...
- Apache2.4+Tomcat7.0整合配置详解
一.简单介绍 Apache.Tomcat Apache HTTP Server(简称 Apache),是 Apache 软件基金协会的一个开放源码的网页服务器,可以在 Windows.Unix.Lin ...
- hdu 6182
A Math Problem Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)To ...
- Autofac三种生命周期
InstancePerLifetimeScope:同一个Lifetime生成的对象是同一个实例 SingleInstance:单例模式,每次调用,都会使用同一个实例化的对象:每次都用同一个对象: In ...
- VUE.js devtool 安装简易教程(转)
最简便的方法是用FQ来通过google应用商店进行安装,但是大多数人还是处在非FQ的状态 尝试过安装Node的方法来安装,但是极其不建议用这个方法安装,非常麻烦,而且必须要有node的基础,非常不接地 ...