上一次【https://www.cnblogs.com/webor2006/p/9508341.html】已经将编译器生成的默认构造方法的字节相关的分析完了,接下来则分析咱们自定义的方法啦,按照顺序来讲的话应该是再分析getA()了:

还是按照方法的结构来分析,先来回忆一下方法的结构:

前两个字节表示访问修饰符,所以跟着上次分析的位置数两个字节:

然后再去修饰符表中去查看一下是哪个修饰符,如下:

接着四个字节分别表示方法名称的索引以及方法描述符的索引,如下:

所以数四个字节:

对应常量池14、15,如下:

确实如咱们的猜想,第二个方法就是getA(),好继续往下分析:

表示方法的属性个数,所以往下数两个字节:

所以说明只有一个属性,接着再数2个字节则表示属性的名称索引,如下:

对应常量池:

如之前所述:每个方法都有一个对应的Code属性, 所以接下来就得来看一下Code属性结构体了,如下:

接着则是attribute_length了,往下数四个字节:

说明整个Code的长度为47个字节,对比一下jclasslib所示:

继续往下:往下两个字节为:

所以往后数四个字节:

max_stack表示这个方法运行的任何时刻所能达到的操作数栈的最大深度为1;max_locals表示方法执行期间创建的局部变量的数目为1,而咱们getA()压根就木有定义局部变量,根据之前分析的默认构造方法可以得知此局部变量为编译器生成的this变量。

继续往下:

表示该方法所包含的字节码的字节数以及具体的指令码,所以往后数4个字节:

长度为5,所以往后再数5个字节则为对应在jclasslib中的代码助记符的信息,也就是方法的执行体,如下:

第一个字节为:

刚好对应aload_0,如下:

接着第二个字节:

对应助记符为:

看一下官网对它的解释:

而且它是有参数的,所以往后数两个字节:

对应常量池为:

所以如jclasslib所看到:

接下来最后一个Code的字节,如下:

对应助记符为:

查看官网说明:

好,接下来则是异常表的信息,如下:

往后数2个字节:

因为该方法木有异常,所以为0,那异常信息就可以忽略了,如下:

接下来则到属性相关的东东了,如下:

往后数两个字节:

说明有两个属性,往下数两个字节则是第一个属性的名字索引,如下:

查看常量池:

表示的是行号表,所以此时就要看一下行号表的结构体了:

接下来数4个字节则是属性的长度attribute_length,如下:

所以接下来的6个字节则为该行号表的信息,如下:

看一下jclasslib:

下面具体来分析一下这10个字节,根据结构体来看:

先2个字节表示属性表有几对映射,如下:

说明有1对映射,然后再回到结构体中,每对映射的内容为:

每对占4个字节,所以:

也就是start_pc=0;line_number=7,对应于jclasslib:

对应的源代码为:

好,方法的第一个属性已经完了,接下来以同样的顺序来查看方法的第二个属性信息了,走2个字节来看属性名称索引,如下:

对应常量表:

它的结构跟LineNumberTable差不多的,往后数四个字节则是局部变量表所占的长度:

长度为12,如jclasslib所示:

然后往后数12个字节则是局部变量的具体信息,如下:

首先两个字节则为局部变量的个数,如下:

说明有一个局部变量,再往后四个字节表示start_pc和length,如下:

如jclasslib所示:

接下来则为局部变量的索引为0,也就是第一个局部变量,如下:

再往后两个个字节则是局部变量对应常量池的索引,如下:

再接下来两个字节则是对该局部变量的一个描述常量索引,如下:

所以对应jclasslib中可以看到:

从这个分析又能证明,对于实例方法,都会有一个this局部变量存在的。

还剩最后两个字节则为stackmaptable信息,JDK1.6加入的,主要做校验检查的,因为0嘛所以后面肯定木有相关的信息了,这里就直接忽略,如下:

至此getA()方法就已经完全分析完了,接着就是第二个方法setA()了:

所以还得来依据方法表来进行分析:

前两个字节表示访问修饰符:

然后再去修饰符表中去查看一下是哪个修饰符,如下:

接着四个字节分别表示方法名称的索引以及方法描述符的索引,如下:

对应常量池16、17,如下:

正如我们所看到的,继续往下分析:

表示方法的属性个数,所以往下数两个字节:

所以说明只有一个属性,接着再数2个字节则表示属性的名称索引,如下:

对应常量池:

是不是对它异常的亲切了,每个方法必然会有这个属性,所以接下来就得来看一下Code属性结构体了,如下:

接着则是attribute_length了,往下数四个字节:

说明整个Code的长度为62个字节,对比一下jclasslib所示:

继续往下:往下两个字节为:

所以往后数四个字节:

max_stack表示这个方法运行的任何时刻所能达到的操作数栈的最大深度为2;max_locals表示方法执行期间创建的局部变量的数目为2,为啥这次变为2个局部变量了呢?因为第一个是隐式的this,第二个则为方法的int参数。

继续往下:

表示该方法所包含的字节码的字节数以及具体的指令码,所以往后数4个字节:

长度为6,所以往后再数6个字节则为对应在jclasslib中的代码助记符的信息,也就是方法的执行体,如下:

第一个字节为:

刚好对应aload_0,如下:

接着第二个字节:

对应助记符为:

看一下官网对它的解释:

第三个字节:

对应助记符为:

看一下官网对它的解释:

而且它是有参数的,所以往后数两个字节:

对应常量池为:

所以如jclasslib所看到:

接下来最后一个Code的字节,如下:

对应助记符为:

至此setA()方法的执行体就已经分析完了。

好,接下来则是异常表的信息,如下:

往后数2个字节:

因为该方法木有异常,所以为0,那异常信息就可以忽略了,如下:

接下来则到属性相关的东东了,如下:

往后数两个字节:

说明该方法有两个属性,往下数两个字节则是第一个属性的名字索引,如下:

也就是对应第10的常量池,为:

该属性用来表示code数组中的字节码和Java代码行数之间的关系。这个属性可以用来在调试的时候定位代码执行的行数。而该属性的结构为:

其中attribute_name_index就是常量索引10,接下来数4个字节则是属性的长度attribute_length,如下:

也就是属性的长度为10,也就是接下来10个字节则为LineNumberTable的属性信息,如下:

看一下jclasslib:

下面具体来分析一下这10个字节,根据结构体来看:

先2个字节表示属性表有几对映射,如下:

说明有两对映射,然后再回到结构体中,每对映射的内容为:

每对占4个字节,先看第一对映射:

也就是start_pc=0;line_number=11,对应于jclasslib:

对应源代码:

接下来看第二对映射:

也就是start_pc=5;line_number=12,对应于jclasslib:

对应源代码:

好,方法的第一个属性已经完了,接下来以同样的顺序来查看方法的第二个属性信息了,走2个字节来看属性名称索引,如下:

对应第11个常量池索引,如下:

它的结构跟LineNumberTable差不多的,往后数四个字节则是局部变量表所占的长度:

长度为22,如jclasslib所示:

然后往后数12个字节则是局部变量的具体信息,首先两个字节则为局部变量的个数,如下:

先分析第一个局部变量,往后四个字节表示start_pc和length,如下:

如jclasslib所示:

接下则为局部变量的索引为0,也就是第一个局部变量,如下

再往后两个字节则是局部变量对应常量池的索引,如下:

再接下来两个字节则是对该局部变量的一个描述常量索引,如下:

所以对应jclasslib中可以看到:

还剩最后两个字节则为stackmaptable信息,JDK1.6加入的,主要做校验检查的,因为0嘛所以后面肯定木有相关的信息了,这里就直接忽略,如下:

再来分析第二个局部变量,往后四个字节表示start_pc和length,如下:

如jclasslib所示:

接下来则为局部变量的索引为1,也就是第二个局部变量:

再往后两个字节则是局部变量对应常量池的索引,如下:

再接下来两个字节则是对该局部变量的一个描述常量索引,如下:

如jclasslib:

还剩最后两个字节则为stackmaptable信息,JDK1.6加入的,主要做校验检查的,这里就直接忽略,如下:

至此!!所有类中的方法相关的字节码就全部分析完了,确实够麻烦,最后则是类的属性信息了如下:

往后两个字节则表明字节码属性的长度:

有一个文件属性,往后两个字节则为属性名称的常量池索引,如下:

对应常量池:

再往后四个字节则为属性所占字节的长度:

说明attribute_length占2个字节,也就是最后剩的两个字节,如下:

对应常量:

如jclasslib所示:

哎呀!!!终于完完整整一字不落的将字节码的每个字节对应的意义给分析完了,超级繁锁,不过,也对Java字节码文件顺间觉得亲切多啦~~

Java字节码整体分析与总结的更多相关文章

  1. 在Eclipse里查看Java字节码

    要理解 Java 字节码,比较推荐的方法是自己尝试编写源码对照字节码学习.其中阅读 Java 字节码的工具必不可少.虽然javap可以以可读的形式展示出.class 文件中字节码,但每次改动源码都需调 ...

  2. JAVA字节码解析

    Java字节码指令 Java 字节码指令及javap 使用说明 ### java字节码指令列表 字节码 助记符 指令含义 0x00 nop 什么都不做 0x01 aconst_null 将null推送 ...

  3. 【转】在Eclipse里查看Java字节码

    要理解 Java 字节码,比较推荐的方法是自己尝试编写源码对照字节码学习.其中阅读 Java 字节码的工具必不可少.虽然javap可以以可读的形式展示出.class 文件中字节码,但每次改动源码都需调 ...

  4. Java字节码(.class文件)格式详解(一)

    原文链接:http://www.blogjava.net/DLevin/archive/2011/09/05/358033.html 小介:去年在读<深入解析JVM>的时候写的,记得当时还 ...

  5. 通过Java字节码发现有趣的内幕之String篇(上)(转)

    原文出处: jaffa 很多时候我们在编写Java代码时,判断和猜测代码问题时主要是通过运行结果来得到答案,本博文主要是想通过Java字节码的方式来进一步求证我们已知的东西.这里没有对Java字节码知 ...

  6. 掌握Java字节码(转)

    Java是一门设计为运行于虚拟机之上的编程语言,因此它需要一次编译,处处运行(当然也是一次编写,处处测试).因此,安装到你系统上的JVM是原生的程序,而运行在它之上的代码是平台无关的.Java字节码就 ...

  7. Java字节码操纵框架ASM小试

    本文主要内容: ASM是什么 JVM指令 Java字节码文件 ASM编程模型 ASM示例 参考资料汇总 JVM详细指令 ASM是什么 ASM是一个Java字节码操纵框架,它能被用来动态生成类或者增强既 ...

  8. Java:从面试题“i++和++i哪个效率高?"开始学习java字节码

    今天看到一道面试题,i++和++i的效率谁高谁低. 面试题的答案是++i要高一点. 我在网上搜了一圈儿,发现很多回答也都是同一个结论. 如果早个几年,我也会认同这个看法,但现在我负责任的说,这个结论是 ...

  9. Java字节码—ASM

    前言 ASM 是什么 官方介绍:ASM is an all purpose Java bytecode manipulation and analysis framework. It can be u ...

随机推荐

  1. 接着上次的python爬虫,今天进阶一哈,局部解析爬取网页数据

    *解析网页数据的仓库 用Beatifulsoup基于lxml包lxml包基于html和xml的标记语言的解析包.可以去解析网页的内容,把我们想要的提取出来. 第一步.导入两个包,项目中必须包含beau ...

  2. 【C/C++开发】ffplay中的FrameQueue的自我理解

    最近在研究ffplay,以下是本人今天在研究FrameQueue的时候整理的笔记,如有错误还请有心人指出来~ //这个队列是一个循环队列,windex是指其中的首元素,rindex是指其中的尾部元素. ...

  3. 【C/C++开发】C++队列缓存的实现

    C++队列缓存的实现 为什么使用队列缓存 c++的队列缓存主要用于解决大数据量并发时的数据存储问题,可以将并发时的数据缓存到队列中,当数据量变小时再匀速写入硬盘中. 引用queue队列 在头文件中引用 ...

  4. eNSP——ACL基础设置

    原理: 实验案例: 拓补图: 实验编址: 1.基础设置 根据实验编址进行基础设置,并检测直连链路的连通性. 2.搭建OSPF网络 在所有路由器运行OSPF协议,通告相应网段到区域0. 在上一个随笔有详 ...

  5. cv2---imread---error

    when I use the cv2.imred() which is absolute path  path = r'C:\\Users\\hp\\Desktop\\常用Python代码\\mycv ...

  6. matplotlib中的imshow()

    import matplotlib.pyplot as plt plt.imshow(x,cmap) x表示要显示的图片变量,cmap为颜色图谱,默认为RGB(A)颜色空间,也可以指定,gray是灰度 ...

  7. uwp,右键浮出获取DataContext(数据上下文)

    列表视图类控件,如ListView/GridView,有时项目需要按下右键浮出选项,来获取Item的DataContext. 下面的示例代码,事先我已经有了一个自定义类Video,并且已经绑定了数据源 ...

  8. Linux 时间以及时间间隔的简单处理.

    最近想知道自己的一个部署脚本的耗时, 中午时间看了一下最简单的Linux 时间函数的处理 我这里的处理非常简单, 仅仅是够用而已. 处理过程. 1. 获取当前时间: time1=`date` 或者是 ...

  9. [转帖]华为鲲鹏云服务器实战:华为云鲲鹏KC1实例 vs. 阿里云G5实例

    鲲鹏云服务器实战:华为云鲲鹏KC1实例 vs. 阿里云G5实例 https://m.ithome.com/html/444828.htm 2019-09-12 15:25IT之家 (阿迷) 今年一月份 ...

  10. Jenkins+maven+gitlab自动化部署之基础环境部署(一)

    从一个二线城市,来到上海,刚入职,老大就给任务,为了减少开发打包部署时间,需要搭建一套自动化部署环境.接到任务后,赶紧上网查找资料,以及了解jenkins作用等等,用了一周时间,了解了个大概,由于都是 ...