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 ...
随机推荐
- redcon, Redis兼容的服务器框架
源代码名称:redcon 源代码网址:http://www.github.com/tidwall/redcon redcon源代码文档 redcon源代码下载 Git URL: 复制代码 git:// ...
- 【VS开发】【数据库开发】libevent windows下基于VS2010的编译
libevent是一个常用的网络库,下面就看看在windows下面编译测试的过程吧. 一 环境 系统:win8.1编译器:VS2013官方下载地址:http://libevent.org/版本:2.0 ...
- matplotlib中的imshow()
import matplotlib.pyplot as plt plt.imshow(x,cmap) x表示要显示的图片变量,cmap为颜色图谱,默认为RGB(A)颜色空间,也可以指定,gray是灰度 ...
- Linux下载安装mysql5.7教程
首先下载mysql 的安装包,可以去官网下载,网址:https://dev.mysql.com/downloads/mysql/ 然后下滑,在这个地方选择你想要安装的版本: 这里我选择的5.7.点击进 ...
- 有关Linux服务器的一些配置
1.Redis部署 1.版本 redis-3.0.72.上传解压 3.编译 make && make install 问题:/bin/sh: cc: command not found ...
- centos7无网络环境下创建基于scratch镜像的Linux镜像,并带有Java运行环境
一.准备 将下载好的jdk以及scratch镜像放在同一文件夹下:这里放在linux:2.0 二.导入scratch镜像 #docker load -i scratch.tar 三.创建dockerf ...
- 自定义模块,time,datetime以及random
自定义模块,time,datetime以及random 1.自定义模块 自定义一个模块 import #导入 (拿工具箱) 模块分类 1.内置模块(标准库) --python解释器自带的.py文件(模 ...
- pandas数据结构之Panel笔记
Panel创建的是三维的表 items:坐标轴0,索引对应的元素是一个DataFrame major_axis:坐标轴1,DataFrame里的行标签 minor_axis:坐标轴2,DataFram ...
- [Vue]vue中路由重定向redirect
1.重定向的地址不需要接收参数 const routes = [ { path: '/', redirect: '/index'}, { path: '/index', component: inde ...
- (一)SpringBoot之简介和安装插件以及HelloWorld第一个程序
一.简介 Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的 ...