路人战队|授人以鱼不如授人以渔,软妹手把手教你javap反编译分解代码( 四 )


路人战队|授人以鱼不如授人以渔,软妹手把手教你javap反编译分解代码
文章图片
由上面这些信息可以推导源代码定义的字段为privateinta;和源码相符 。
懂了字段表之后 , 方法表结构几乎和字段表结构是一模一样的 , 通过访问标志、名称索引、描述符索引可清楚的表达方法的定义 。 除了一些标志位不同 , 毕竟有些修饰符可以修饰方法不能修饰字段 , 有些修饰符可以修饰字段但是方法没有 , 内容如下对比字段表标志有添加有删减有相同:
路人战队|授人以鱼不如授人以渔,软妹手把手教你javap反编译分解代码
文章图片
重载(Overload)一个方法:
要与原方法具有相同的简单名称要与原方法有不同的特征签名(特征签名就是一个方法中各个参数在常量池中字段符号的引用集合 , 因为返回值不在特征签名里面 , 所以返回值不同作为重载条件)
路人战队|授人以鱼不如授人以渔,软妹手把手教你javap反编译分解代码
文章图片
u20x0004->第一个跟着的是方法数量,这个类有4个方法表数据 , 分别是add(),multi(),main()和构造器方法以下是第一个方法表内容:u20x0001public为真 , 其他为假u20x000d方法简单名称name_index,由上面JAVAP常量表可知#14为()v,v由描述符含义可知是特殊类型void,()代表无参数 , 即构造函数u20x000e方法描述符descriptor_index,由上面JAVAP常量表可知#15指Code,Code之后再讲u20x0001attribute_count,属性表集合有一项属性用于存储一些额外信息attribute_info0x000f由JAVAP看到的指令 , 指向#15,即对应常量”Code“ , 说明此属性是方法的字节码描述复制代码
路人战队|授人以鱼不如授人以渔,软妹手把手教你javap反编译分解代码
文章图片
第一个方法:
路人战队|授人以鱼不如授人以渔,软妹手把手教你javap反编译分解代码
文章图片
讲了大半年 , 还只是讲了字段 , 方法头这些内容可以通过访问标志 , 名称索引 , 方法描述符来表达清楚 , 这些都是些元数据 , 那么方法体上哪去了呢?这就要属性表出山啦!
有眼力见的朋友可能已经讲字段表和方法表的时候 , 就发现了属性表的踪影 , 用来描述某些场景专有信息的 , 与上面讲到的其他的数据项目不同的是 , 其他数据项目要求严格的顺序 , 长度和内容 , 属性表的限制是放养状态 , 不要求各个属性表具有严格的顺序 , 只要不与已有的属性名重复 , 任何人实现的编译器都可以向属性表中写入自己定义的属性信息 , JVM会运行时会忽略掉他不认识的 。
Java程序方法体中的代码经过Javac编译处理后 , 最终变为字节码指令存储在Code属性中 , Code属性出现在方法表的属性集合之中 。 但并非所有方法表都有Code属性 , 例如抽象类或接口 。
code属性表结构如图:
路人战队|授人以鱼不如授人以渔,软妹手把手教你javap反编译分解代码
文章图片
attribute_name_index指向CONSTANT_Utf8_info类型常量的值固定为“Code”attribute_length标识属性值的总长度max_stack代表了操作数据(OperandStacks)深度的最大值max_locals代表了局部变量所表示的存储空间单位:Slotcode_length和code是用来存储Java源程序编译后产生的字节码指令 , codelength代表字节码长度 , code是用于存储字节码指令的一系列字节流 。 字节码指令 , 每个指令字节码代表的指令含义 , 是否需参数 , 是u1类型的单字节 , 取值范围是0x00~0xFF , 即0~255 , 一共可以表达256条指令 , 目前JVM规范已经定义了约200条指令了 。属性有很多的 , JAVA虚拟机规范预定义了21项 , 我们平时能看到的都有
路人战队|授人以鱼不如授人以渔,软妹手把手教你javap反编译分解代码


推荐阅读