继续跟着上一次【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字节码方法表与属性表详解的更多相关文章

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

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

  2. Java线程通讯方法之wait()、nofity() 详解

    Java线程通讯方法之wait().nofity() 详解 本文将探讨以下问题: synchronized 代码块使用 notify()与notifyAll()的区别 Java wait(),noti ...

  3. JVM Java字节码方法表与属性

    方法表 1.methods_count  method_info,前三个字段和field_info一样 2.方法的属性结构 方法中的每个属性都是一个attribut_info结构 JVM定义了部分at ...

  4. Java字节码方法表与属性表深度剖析

    方法表: 在上一次咱们已经分析到了字段信息了,如下: 紧接着就是方法相关的信息了: 而它展开之后的结构为: 所以往后数2个字节,看一下方法的总数: 3个方法,可咱们只定义了两个方法呀: 因为编译器会为 ...

  5. Java字节码方法表结构深度剖析

    继续上一次[https://www.cnblogs.com/webor2006/p/9459681.html]的字节码分析,这次来分析一下最为复杂的方法表的信息,如下: 而上一次分析到了属性表的位置在 ...

  6. Java线程阻塞方法sleep()和wait()精炼详解

    版权声明:因为个人水平有限,文章中可能会出现错误,如果你觉得有描述不当.代码错误等内容或者有更好的实现方式,欢迎在评论区告诉我,即刻回复!最后,欢迎关注博主!谢谢 https://blog.csdn. ...

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

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

  8. 从 HelloWorld 看 Java 字节码文件结构

    很多时候,我们都是从代码层面去学习如何编程,却很少去看看一个个 Java 代码背后到底是什么.今天就让我们从一个最简单的 Hello World 开始看一看 Java 的类文件结构. 在开始之前,我们 ...

  9. 空手套白狼,硬阅java字节码class文件

    如下,是一些java字节码也就是原始的class文件,当应用部署到线上之后,我们能够看到的也就是这样的字样了.那么怎样解呢?就让我们一起,来解读解读字节码吧! Offset A B C D E F C ...

随机推荐

  1. Fakes里的stub和shim的区别

    stub常用于虚拟接口.类.方法,无法重写静态方法(stub需要传递到具体调用代码中) shim常用于重写静态方法(在ShimsContext.Create()作用域内,拦截Runtime动态修改方法 ...

  2. JavaScript、TypeScript、ES6三者之间的联系和区别

    ES6是什么 ECMAScript 6.0(以下简称ES6)是JavaScript语言(现在是遵循ES5标准)的下一代标准,已经在2015年6月正式发布了.它的目标,是使得JavaScript语言可以 ...

  3. Java变量与数据类型之三:数据类型与转义字符

    大家好,小乐又来了,上一篇:乐字节Java变量与数据类型之二:Java常量与变量, 今天接着讲Java变量与数据类型之三:数据类型与转义字符 一.数据类型 1.定义 Java是一种强类型语言,针对每种 ...

  4. Django之Form与ModelForm组件

    Django之Form与ModelForm组件 1.Form介绍 Form组件的主要功能如下: 生成页面可用的HTML标签 对用户提交的数据进行校验 O 保留上次的输入内容 普通方式手写注册功能 vi ...

  5. 利用Python进行数据分析_Pandas_绘图和可视化_Matplotlib

    1 认识Figure和Subplot import matplotlib.pyplot as plt matplotlib的图像都位于Figure对象中 fg = plt.figure() 通过add ...

  6. qt聊天室bug-- error: no matching function for call to 'Ui::Widget::setupUi(Widget*)' ui->setupUi(this); ^

  7. java之集合那些事

    集合概述: 集合和数组都可以保存多个对象,但是数组的长度不可变,集合可以保存数量变化的数据.java中的集合类主要由两个接口派生出,Collection和Map Collection接口和Iterat ...

  8. delete删除数据造成归档日志增加,操作系统空间不足导致数据库hang住

    业务需求,对日志表历史数据进行清理.历史表均很大,使用delete 操作删除90天前的数据. 第一部分:快速删除数据 SQL> alter table CC.F_LOG parallel ; S ...

  9. ligerui tab 部分记载

    打开一个Tab $(".strength_box").click(function () { var id = $(this).attr("data"); va ...

  10. 3D数学基础_图形与游戏开发

    https://blog.csdn.net/popy007/article/list/2?t=1&  //向量计算相关文章 https://www.baidu.com/link?url=48C ...