Java中class文件结构分析二

news2024/9/21 0:50:58

第17个常量池:01 00 15 28 4C 6A 61 76 61 2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29 56

01:tag位表示的是utf8类型的字面量常量

00 15 二个字节表示的是字面量常量的长度为21

接下来21个字节: 28 4C 6A 61 76 61 2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29 56 表示字符串 (Ljava/lang/String;)V

第18个常量:01 00 10 4D 65 74 68 6F 64 50 61 72 61 6D 65 74 65 72 73

01:tag位表示的是utf8类型的字面量常量

00 10 二个字节表示的是字面量常量的长度为16

接下来16个字节: 4D 65 74 68 6F 64 50 61 72 61 6D 65 74 65 72 73 表示字符串MethodParameters

第19个常量: 01 00 0A 53 6F 75 72 63 65 46 69 6C 65

01:tag位表示的是utf8类型的字面量常量

00 0A 二个字节表示的是字面量常量的长度为10

接下来10个字节: 53 6F 75 72 63 65 46 69 6C 65 表示字符串SourceFile

第20个常量分析:01 00 13 54 75 6C 69 6E 67 42 79 74 65 43 6F 64 65 2E 6A 61 76 61

01:tag位表示的是utf8类型的字面量常量

00 13 二个字节表示的是字面量常量的长度为19

接下来19个字节: 54 75 6C 69 6E 67 42 79 74 65 43 6F 64 65 2E 6A 61 76 61 表示字符串TulingByteCode.java

21个常量池分析: 0C 00 07 00 08

0C:tag位表示的是符号引用 nameAndType_info类型的

00 07 指向索引为7的常量池#7

00 08 指向常量池8的位置#8

第22个常量池:0C 00 05 00 06

0C:tag位表示的是符号引用 nameAndType_info类型的

00 05 指向索引为7的常量池#5

00 06 指向常量池8的位置#6

第23个常量池:

01 00 31 63 6F 6D 2F 74 75 6C 69 6E 67 2F 73 6D 6C 7A 2F 6A 76 6D 2F 63 6C 61 73 73 62 79 61 74 65 63 6F 64 65 2F 54 75 6C 69 6E 67 42 79 74 65 43 6F 64 65

01:tag位表示的是utf8类型的字面量常量

00 31 二个字节表示的是字面量常量的长度为49

接下来49个字节: 63 6F 6D 2F 74 75 6C 69 6E 67 2F 73 6D 6C 7A 2F 6A 76 6D 2F 63 6C 61 73 73 62 79 61 74 65 63 6F 64 65 2F 54 75 6C 69 6E 67 42 79 74 65 43 6F 64 65 表示字符串com/tuling/smlz/jvm/classbyatecode/TulingByteCode

第24个常量池:01 00 10 6A 61 76 61 2F 6C 61 6E 67 2F 4F 62 6A 65 63 74

01:tag位表示的是utf8类型的字面量常量

00 10 二个字节表示的是字面量常量的长度为16

接下来16个字节: 6A 61 76 61 2F 6C 61 6E 67 2F 4F 62 6A 65 63 74 表示字符串java/lang/Object

 

四:Class文件结构访问标识符号解析 Access_flag

解析我们的class文件是类还是接口,是否定义为public的,是否是abstract,是否被final修饰。

访问标志符号占用二个字节: 00 21

我们发现这个class文件的访问标识字节是0x0021,我们去查询手册中查询没有这个对应的?

原因:jvm规范并没有穷举出所以的类型 而是通过位运算的出来的.

0x0021 = 0x0020 位运算 0x0001 那么我们可以得出这个class的访问权限是ACC_PUBLIC 和ACC_SUPER

五: This class name的描述当前的所属类

this class name 占用二个字节:00 03 表示索引 指向的是常量池中的第三个常量

所以我们的this class name:表示当前类 com/tuling/smlz/jvm/classbyatecode/TulingByteCode

第六部分: super class name (当前class的父类名字)

同样占用二个字节:00 04 也是表示索引值,指向常量池中第四个常量

根据第三部分常量池的分析第四个常量池得出.

所以我们的super class name表示的意思是: java/lang/Object

第七部分:接口信息(**标注 我们的当前class没有实现接口为了演示效果我用的另外一个类演示) 这个类我们实现了二个接口 分别为ITulingIntf ITulingIntf

 

00 02表示我们实现了几个接口 这里很明星我们是实现了二个接口

00 08(第一个接口) 表示的是接口的位于常量池中的索引.#8

所以00 08指向的接口是:com/tuling/smlz/jvm/classbyatecode/ITulingIntf

00 09(第二个接口)表示的是接口的位于常量池中的索引#9

第八部分:字段表信息

作用:用于描述类和接口中声明的变量,包括类变量和实例变量

但是不包括方法的局部变量

仅仅的接着接口信息后面的是字段描述 00 01 00 02 00 05 00 06 00 00

00 01 二个字节表示的是field_info字段表的个数 这里很显然只有一个

字段结构体

00 02 00 05 00 06 00 00

所以00 02 表示访问修饰符号为ACC_PRIVATE

所以00 05 表示的是字段的名称 指向的是常量池中第五个常量

所以00 06是我们的字段的描述符: 指向的是常量池中第六个常量

00 00 表示是属性表的个数 这里为0表示后面是没有属性表集合

通过jclasslib分析和我们自己分析的出来的结论一致

第九部分:方法表信息分析

00 03 表示我们的方法的个数为三个

方法表结构:如下

第一个方法的前八个字节 00 01 00 07 00 08 00 01

00 01:表示的是方法的修饰符 表示的是acc_public

00 07:表示的是方法的名称 表示指向常量池中第7个常量,表示方法的名称

<init>表示构造方法

 00 08:方法的描述符号,表示指向常量池第八个常量 为()V 表示的是无参无返回值

00 01表示有一个方法属性的个数

9.1)方法表中的属性表attribute_info结构图

00 09 00 00 00 2F

00 09:表示的是方法属性名称的索引指向常量池#9 表示是Code属性

00 00 00 2F 标识的info的长度 长度值为47个字节 也就是说 会占据47个字节作为code的值

后续的47个字节是我们的Code属性的所占用的字节 (特别特别需要注意这47个字节从Code属性表中第三个开始也就是max_stack开始)

code_attribute属性表结构如下

00 01 00 01 00 00 00 05 2A B7 00 01 B1 00 00 00 02 00 0A 00 00 00 06 00 01 00 00 00 06 00 0B 00 00 00 0C 00 01 00 00 00 05 00 0C 00 0D 00 00

00 01 00 01 00 00 00 05 2A B7 00 01 B1 00 00 00 02 00 0A 00 00 00 06 00 01 00 00 00 06 00 0B 00 00 00 0C 00 01 00 00 00 05 00 0C 00 0D 00 00

(max_stack)表示的是我们最大操作数栈的深度为1

00 01 00 01 00 00 00 05 2A B7 00 01 B1 00 00 00 02 00 0A 00 00 00 06 00 01 00 00 00 06 00 0B 00 00 00 0C 00 01 00 00 00 05 00 0C 00 0D 00 00

(max_locals)标识的是局部变量表变量的个数

00 01 00 01 00 00 00 05 2A B7 00 01 B1 00 00 00 02 00 0A 00 00 00 06 00 01 00 00 00 06 00 0B 00 00 00 0C 00 01 00 00 00 05 00 0C 00 0D 00 00

(Code_lenth)四个字节表示的是我们指令的长度为五

字节码指令助记符号 2A B7 00 01 B1

0x2A:对应的字节码注记符是aload_0,作用就是把当前调用方法的栈帧中的局部变量表索引位置为0的局部变量推送到操作数栈的栈顶.

0xB7:表示是 invokespecial 调用父类的方法 那么后面需要接入二个字节表示调用哪个方法 所以 00 01 表示的是指向常量池中第一个位置为为如下结构

0xB1 对应的字节码指令值retrun 表示retrun void from method;

异常信息表的个数为 00 00 表示方法没有抛出异常

00 01 00 01 00 00 00 05 2A B7 00 01 B1 00 00 00 02 00 0A 00 00 00 06 00 01 00 00 00 06 00 0B 00 00 00 0C 00 01 00 00 00 05 00 0C 00 0D 00 00

表示Code_attribute结构中属性表的个数为00 02 表示为2个

00 01 00 01 00 00 00 05 2A B7 00 01 B1 00 00 00 02 00 0A 00 00 00 06 00 01 00 00 00 06 00 0B 00 00 00 0C 00 01 00 00 00 05 00 0C 00 0D 00 00

LineNumberTable结构体为下图:

00 01 00 01 00 00 00 05 2A B7 00 01 B1 00 00 00 02 00 0A 00 00 00 06 00 01 00 00 00 06 00 0B 00 00 00 0C 00 01 00 00 00 05 00 0C 00 0D 00 00

这二个字节表示的是我们属性名称的索引attribute_name_index指向常量池中的00 0A #10个常量池

attribute_length:属性的长度占用四个字节: 表示后面00 00 00 06 六个字节是我们属性的内容

00 01 00 01 00 00 00 05 2A B7 00 01 B1 00 00 00 02 00 0A 00 00 00 06 00 01 00 00 00 06 00 0B 00 00 00 0C 00 01 00 00 00 05 00 0C 00 0D 00 00

这里的00 01 表示的是有几对指令码和源码映射关系 这里明显只有一对

00 01 00 01 00 00 00 05 2A B7 00 01 B1 00 00 00 02 00 0A 00 00 00 06 00 01 00 00 00 06 00 0B 00 00 00 0C 00 01 00 00 00 05 00 0C 00 0D 00 00

00 01 00 01 00 00 00 05 2A B7 00 01 B1 00 00 00 02 00 0A 00 00 00 06 00 01 00 00 00 06 00 0B 00 00 00 0C 00 01 00 00 00 05 00 0C 00 0D 00 00

这里表示 第一个指令码映射的是第六行源码

LocalVariableTable 本地方法变量表结构分析

00 01 00 01 00 00 00 05 2A B7 00 01 B1 00 00 00 02 00 0A 00 00 00 06 00 01 00 00 00 06 00 0B 00 00 00 0C 00 01 00 00 00 05 00 0C 00 0D 00 00

本地变量表的名称的索引指向attribute_name_index的是常量池11的位置:

本地变量表中属性的长度attribute_length:12长度

00 01 00 01 00 00 00 05 2A B7 00 01 B1 00 00 00 02 00 0A 00 00 00 06 00 01 00 00 00 06 00 0B 00 00 00 0C 00 01 00 00 00 05 00 0C 00 0D 00 00

本地变量表local_variable_table_length的个数

00 01 00 01 00 00 00 05 2A B7 00 01 B1 00 00 00 02 00 0A 00 00 00 06 00 01 00 00 00 06 00 0B 00 00 00 0C 00 01 00 00 00 05 00 0C 00 0D 00 00

local_vabiable_info的结构

start_pc:这个局部变量的生命周期开始的字节码偏移量 占用二个字节

00 01 00 01 00 00 00 05 2A B7 00 01 B1 00 00 00 02 00 0A 00 00 00 06 00 01 00 00 00 06 00 0B 00 00 00 0C 00 01 00 00 00 05 00 0C 00 0D 00 00

length:作用范围覆盖的长度 占用二个字节

00 01 00 01 00 00 00 05 2A B7 00 01 B1 00 00 00 02 00 0A 00 00 00 06 00 01 00 00 00 06 00 0B 00 00 00 0C 00 01 00 00 00 05 00 0C 00 0D 00 00

name_index:表示局部变量的名称 二个字节

00 0C表示指向常量池12的位置

00 01 00 01 00 00 00 05 2A B7 00 01 B1 00 00 00 02 00 0A 00 00 00 06 00 01 00 00 00 06 00 0B 00 00 00 0C 00 01 00 00 00 05 00 0C 00 0D 00 00

desc_index:表示局部变量描述符索引 二个字节

00 0D表示指向常量池13的位置

00 01 00 01 00 00 00 05 2A B7 00 01 B1 00 00 00 02 00 0A 00 00 00 06 00 01 00 00 00 06 00 0B 00 00 00 0C 00 01 00 00 00 05 00 0C 00 0D 00 00

index:index是这个局部变量在栈帧局部变量表中Slot的位置。当这个变量数据类型是64位类型时(double和long),它占用的Slot为index和index+1两个

00 01 00 01 00 00 00 05 2A B7 00 01 B1 00 00 00 02 00 0A 00 00 00 06 00 01 00 00 00 06 00 0B 00 00 00 0C 00 01 00 00 00 05 00 0C 00 0D 00 00

第二个方法的字节码

00 01 00 0E 00 0F 00 01 00 09 00 00 00 2F 00 01 00 01 00 00 00 05 2A B4 00 02 B0 00 00 00 02 00 0A 00 00 00 06 00 01 00 00 00 0B 00 0B 00 00 00 0C 00 01 00 00 00 05 00 0C 00 0D 00 00

1)方法访问标记符号:

0x0001我们根据访问权限修饰符号查询可得 访问权限是ACC_PUBLIC

00 01 00 0E 00 0F 00 01 00 09 00 00 00 2F 00 01 00 01 00 00 00 05 2A B4 00 02 B0 00 00 00 02 00 0A 00 00 00 06 00 01 00 00 00 0B 00 0B 00 00 00 0C 00 01 00 00 00 05 00 0C 00 0D 00 00

2)方法名称: 00 0E指向常量池中#14的位置

00 01 00 0E 00 0F 00 01 00 09 00 00 00 2F 00 01 00 01 00 00 00 05 2A B4 00 02 B0 00 00 00 02 00 0A 00 00 00 06 00 01 00 00 00 0B 00 0B 00 00 00 0C 00 01 00 00 00 05 00 0C 00 0D 00 00

3)方法描述符号:00 0F 指向我们的常量池#15的位置

00 01 00 0E 00 0F 00 01 00 09 00 00 00 2F 00 01 00 01 00 00 00 05 2A B4 00 02 B0 00 00 00 02 00 0A 00 00 00 06 00 01 00 00 00 0B 00 0B 00 00 00 0C 00 01 00 00 00 05 00 0C 00 0D 00 00

4)方法表属性个数 00 01 表示一个

00 01 00 0E 00 0F 00 01 00 09 00 00 00 2F 00 01 00 01 00 00 00 05 2A B4 00 02 B0 00 00 00 02 00 0A 00 00 00 06 00 01 00 00 00 0B 00 0B 00 00 00 0C 00 01 00 00 00 05 00 0C 00 0D 00 00

5)方法结构体中的attribute_info的结构体

5.1)attribute_info.attribute_name_index 表示的数属性名称索引 00 09指向常量池的位置: Code

00 01 00 0E 00 0F 00 01 00 09 00 00 00 2F 00 01 00 01 00 00 00 05 2A B4 00 02 B0 00 00 00 02 00 0A 00 00 00 06 00 01 00 00 00 0B 00 0B 00 00 00 0C 00 01 00 00 00 05 00 0C 00 0D 00 00

5.2)attribute_info.attribute_length表示的是我们属性的长度 00 00 00 2F

表示后面47个字节都是我们的Code_info结构体

00 01 00 0E 00 0F 00 01 00 09 00 00 00 2F 00 01 00 01 00 00 00 05 2A B4 00 02 B0 00 00 00 02 00 0A 00 00 00 06 00 01 00 00 00 0B 00 0B 00 00 00 0C 00 01 00 00 00 05 00 0C 00 0D 00 00

5.3)Code_info结构体如图所示

5.3.1)Code_info.max_stack方法操作数栈的深度

00 01表示方法操作数栈的深度为1

00 01 00 0E 00 0F 00 01 00 09 00 00 00 2F 00 01 00 01 00 00 00 05 2A B4 00 02 B0 00 00 00 02 00 0A 00 00 00 06 00 01 00 00 00 0B 00 0B 00 00 00 0C 00 01 00 00 00 05 00 0C 00 0D 00 00

5.3.2)Code_info.max_locals方法局部变量表的个数

00 01方法局部变量表的个数 1

00 01 00 0E 00 0F 00 01 00 09 00 00 00 2F 00 01 00 01 00 00 00 05 2A B4 00 02 B0 00 00 00 02 00 0A 00 00 00 06 00 01 00 00 00 0B 00 0B 00 00 00 0C 00 01 00 00 00 05 00 0C 00 0D 00 00

5.3.3)Code_info.code_length 指令码的长度 00 00 00 05 后面紧接着5个字节就是我们的具体指令码

00 01 00 0E 00 0F 00 01 00 09 00 00 00 2F 00 01 00 01 00 00 00 05 2A B4 00 02 B0 00 00 00 02 00 0A 00 00 00 06 00 01 00 00 00 0B 00 0B 00 00 00 0C 00 01 00 00 00 05 00 0C 00 0D 00 00

5.3.4)Code_info.code[code_length] 表示后面五个字节就是我们的指令码

00 01 00 0E 00 0F 00 01 00 09 00 00 00 2F 00 01 00 01 00 00 00 05 2A B4 00 02 B0 00 00 00 02 00 0A 00 00 00 06 00 01 00 00 00 0B 00 0B 00 00 00 0C 00 01 00 00 00 05 00 0C 00 0D 00 00

①:0x2A:对应的字节码注记符是aload_0,作用就是把当前调用方法的栈帧中的局部变量表索引位置为0的局部变量推送到操作数栈的栈顶.

②:0xb4 getfield 获取指定类的实例域,并将其值压入栈顶 后面是操作的字段

00 02表示常量池索引第二位置

B4 00 02 表示的意思就是把userName类型实例变量的引用压入方法的操作数栈

③:0xB4---->表示为aretrun 返回 从当前方法返回对象引用

5.3.5)Code_info.exception_table_length 异常表的个数: 00 00表示方法没有异常

00 01 00 0E 00 0F 00 01 00 09 00 00 00 2F 00 01 00 01 00 00 00 05 2A B4 00 02 B0 00 00 00 02 00 0A 00 00 00 06 00 01 00 00 00 0B 00 0B 00 00 00 0C 00 01 00 00 00 05 00 0C 00 0D 00 00

5.3.6)code_info.attribute_count 表示code_info属性attribute_info的个数 2个

00 01 00 0E 00 0F 00 01 00 09 00 00 00 2F 00 01 00 01 00 00 00 05 2A B4 00 02 B0 00 00 00 02 00 0A 00 00 00 06 00 01 00 00 00 0B 00 0B 00 00 00 0C 00 01 00 00 00 05 00 0C 00 0D 00 00

5.3.7)code_info.attribute_info[1]

①:00 0A表示为attribute_name_index指向常量池10的位置

00 01 00 0E 00 0F 00 01 00 09 00 00 00 2F 00 01 00 01 00 00 00 05 2A B4 00 02 B0 00 00 00 02 00 0A 00 00 00 06 00 01 00 00 00 0B 00 0B 00 00 00 0C 00 01 00 00 00 05 00 0C 00 0D 00 00

②: 00 00 00 06 表示的是attribute_length 表示长度,接着后面6个字节是我们的

line_number_info的结构体所再用的字节

00 01 00 0E 00 0F 00 01 00 09 00 00 00 2F 00 01 00 01 00 00 00 05 2A B4 00 02 B0 00 00 00 02 00 0A 00 00 00 06 00 01 00 00 00 0B 00 0B 00 00 00 0C 00 01 00 00 00 05 00 0C 00 0D 00 00

③:line_number_info结构体

00 01:表示字节码和源码映射的对数 01表示一对

00 00: 方法中的字节码的行号

00 0B: 源码中的行号 11行

00 01 00 0E 00 0F 00 01 00 09 00 00 00 2F 00 01 00 01 00 00 00 05 2A B4 00 02 B0 00 00 00 02 00 0A 00 00 00 06 00 01 00 00 00 0B 00 0B 00 00 00 0C 00 01 00 00 00 05 00 0C 00 0D 00 00

5.3.7)code_info.attribute_info[2]

00 01 00 0E 00 0F 00 01 00 09 00 00 00 2F 00 01 00 01 00 00 00 05 2A B4 00 02 B0 00 00 00 02 00 0A 00 00 00 06 00 01 00 00 00 0B 00 0B 00 00 00 0C 00 01 00 00 00 05 00 0C 00 0D 00 00

attribute_name_index 00 0B 表示的是指向我们的常量池中11的位置 为LocalVariableTable

attribute_length:00 00 00 0C 标识属性的长度为12,那么后面的12个字符就是我们的属性表的内容

local_varibale_info表的结构体

00 01 00 0E 00 0F 00 01 00 09 00 00 00 2F 00 01 00 01 00 00 00 05 2A B4 00 02 B0 00 00 00 02 00 0A 00 00 00 06 00 01 00 00 00 0B 00 0B 00 00 00 0C 00 01 00 00 00 05 00 0C 00 0D 00 00

start_pc:这个局部变量的生命周期开始的字节码偏移量 占用二个字节

00 01 00 01 00 00 00 05 2A B7 00 01 B1 00 00 00 02 00 0A 00 00 00 06 00 01 00 00 00 06 00 0B 00 00 00 0C 00 01 00 00 00 05 00 0C 00 0D 00 00

length:作用范围覆盖的长度 占用二个字节

00 01 00 01 00 00 00 05 2A B7 00 01 B1 00 00 00 02 00 0A 00 00 00 06 00 01 00 00 00 06 00 0B 00 00 00 0C 00 01 00 00 00 05 00 0C 00 0D 00 00

name_index:表示局部变量的名称 二个字节

00 0C表示指向常量池12的位置

00 01 00 01 00 00 00 05 2A B7 00 01 B1 00 00 00 02 00 0A 00 00 00 06 00 01 00 00 00 06 00 0B 00 00 00 0C 00 01 00 00 00 05 00 0C 00 0D 00 00

desc_index:表示局部变量描述符索引 二个字节

00 0D表示指向常量池13的位置

00 01 00 01 00 00 00 05 2A B7 00 01 B1 00 00 00 02 00 0A 00 00 00 06 00 01 00 00 00 06 00 0B 00 00 00 0C 00 01 00 00 00 05 00 0C 00 0D 00 00

index:index是这个局部变量在栈帧局部变量表中Slot的位置。当这个变量数据类型是64位类型时(double和long),它占用的Slot为index和index+1两个

00 01 00 01 00 00 00 05 2A B7 00 01 B1 00 00 00 02 00 0A 00 00 00 06 00 01 00 00 00 06 00 0B 00 00 00 0C 00 01 00 00 00 05 00 0C 00 0D 00 00

第三个方法的字节码文件分析

00 01 00 10 00 11 00 02 00 09 00 00

00 3E 00 02 00 02 00 00 00 06 2A 2B B5 00 02 B1

00 00 00 02 00 0A 00 00 00 0A 00 02 00 00 00 15

00 05 00 16 00 0B 00 00 00 16 00 02 00 00 00 06

00 0C 00 0D 00 00 00 00 00 06 00 05 00 06 00 01

00 12 00 00 00 05 01 00 05 00 00

1)访问权限修饰符(这个权限修饰符为0x0001)

那么权限符是acc_public

00 01 00 10 00 11 00 02 00 09 00 00

00 3E 00 02 00 02 00 00 00 06 2A 2B B5 00 02 B1

00 00 00 02 00 0A 00 00 00 0A 00 02 00 00 00 15

00 05 00 16 00 0B 00 00 00 16 00 02 00 00 00 06

00 0C 00 0D 00 00 00 00 00 06 00 05 00 06 00 01

00 12 00 00 00 05 01 00 05 00 00

2)方法名称索引指向常量池中的#16

#16 = Utf8 setUserName

00 01 00 10 00 11 00 02 00 09 00 00

00 3E 00 02 00 02 00 00 00 06 2A 2B B5 00 02 B1

00 00 00 02 00 0A 00 00 00 0A 00 02 00 00 00 15

00 05 00 16 00 0B 00 00 00 16 00 02 00 00 00 06

00 0C 00 0D 00 00 00 00 00 06 00 05 00 06 00 01

00 12 00 00 00 05 01 00 05 00 00

3)方法描述符号索引 指向常量池中#17的位置

#17 = Utf8 (Ljava/lang/String;)V

00 01 00 10 00 11 00 02 00 09 00 00

00 3E 00 02 00 02 00 00 00 06 2A 2B B5 00 02 B1

00 00 00 02 00 0A 00 00 00 0A 00 02 00 00 00 15

00 05 00 16 00 0B 00 00 00 16 00 02 00 00 00 06

00 0C 00 0D 00 00 00 00 00 06 00 05 00 06 00 01

00 12 00 00 00 05 01 00 05 00 00

4)该方法属性表的个数 为2个

00 01 00 10 00 11 00 02 00 09 00 00

00 3E 00 02 00 02 00 00 00 06 2A 2B B5 00 02 B1

00 00 00 02 00 0A 00 00 00 0A 00 02 00 00 00 15

00 05 00 16 00 0B 00 00 00 16 00 02 00 00 00 06

00 0C 00 0D 00 00 00 00 00 06 00 05 00 06 00 01

00 12 00 00 00 05 01 00 05 00 00

4.1)第一个属性表Code属性表结构

①: 属性名称索引 指向常量池第九个位置

#9 = Utf8 Code

00 01 00 10 00 11 00 02 00 09 00 00

00 3E 00 02 00 02 00 00 00 06 2A 2B B5 00 02 B1

00 00 00 02 00 0A 00 00 00 0A 00 02 00 00 00 15

00 05 00 16 00 0B 00 00 00 16 00 02 00 00 00 06

00 0C 00 0D 00 00 00 00 00 06 00 05 00 06 00 01

00 12 00 00 00 05 01 00 05 00 00

②:属性长度 占用四个字节,四个字节计算出来的字节数字就是我们的Code属性内容

00 00 00 3E 转换成62个字节,那么我们后面的62个字节是我们的属性内容

00 01 00 10 00 11 00 02 00 09 00 00

00 3E 00 02 00 02 00 00 00 06 2A 2B B5 00 02 B1

00 00 00 02 00 0A 00 00 00 0A 00 02 00 00 00 15

00 05 00 16 00 0B 00 00 00 16 00 02 00 00 00 06

00 0C 00 0D 00 00 00 00 00 06 00 05 00 06 00 01

00 12 00 00 00 05 01 00 05 00 00

③:本方法最大操作数深度为2

00 01 00 10 00 11 00 02 00 09 00 00

00 3E 00 02 00 02 00 00 00 06 2A 2B B5 00 02 B1

00 00 00 02 00 0A 00 00 00 0A 00 02 00 00 00 15

00 05 00 16 00 0B 00 00 00 16 00 02 00 00 00 06

00 0C 00 0D 00 00 00 00 00 06 00 05 00 06 00 01

00 12 00 00 00 05 01 00 05 00 00

④:局部变量表的大小为2

00 01 00 10 00 11 00 02 00 09 00 00

00 3E 00 02 00 02 00 00 00 06 2A 2B B5 00 02 B1

00 00 00 02 00 0A 00 00 00 0A 00 02 00 00 00 15

00 05 00 16 00 0B 00 00 00 16 00 02 00 00 00 06

00 0C 00 0D 00 00 00 00 00 06 00 05 00 06 00 01

00 12 00 00 00 05 01 00 05 00 00

⑤:jvm指令码长度 ,占用四个字节 00 00 00 06

00 01 00 10 00 11 00 02 00 09 00 00

00 3E 00 02 00 02 00 00 00 06 2A 2B B5 00 02 B1

00 00 00 02 00 0A 00 00 00 0A 00 02 00 00 00 15

00 05 00 16 00 0B 00 00 00 16 00 02 00 00 00 06

00 0C 00 0D 00 00 00 00 00 06 00 05 00 06 00 01

00 12 00 00 00 05 01 00 05 00 00

⑥:jvm 指令解析 6个字节的指令码2A 2B B5 00 02 B1

00 01 00 10 00 11 00 02 00 09 00 00

00 3E 00 02 00 02 00 00 00 06 2A 2B B5 00 02 B1

00 00 00 02 00 0A 00 00 00 0A 00 02 00 00 00 15

00 05 00 16 00 0B 00 00 00 16 00 02 00 00 00 06

00 0C 00 0D 00 00 00 00 00 06 00 05 00 06 00 01

00 12 00 00 00 05 01 00 05 00 00

a) 0x2A->aload_0:表示把引用类型的压到我们操作数栈栈顶

b) 0x2B->aload_1:把我们第二个引用类型压入到操作数栈顶

c)0xB5->putFiled 把我们的栈顶的值赋值给实例变量

d)00 02: 表示putFiled的字端,表示操作的对象 指向我们的常量池#2的位置

e)0xB1:->从当前方法返回void

⑦:exception_table_length 异常表长度 为0,那么异常表个数为0

00 01 00 10 00 11 00 02 00 09 00 00

00 3E 00 02 00 02 00 00 00 06 2A 2B B5 00 02 B1

00 00 00 02 00 0A 00 00 00 0A 00 02 00 00 00 15

00 05 00 16 00 0B 00 00 00 16 00 02 00 00 00 06

00 0C 00 0D 00 00 00 00 00 06 00 05 00 06 00 01

00 12 00 00 00 05 01 00 05 00 00

⑧:Code属性表的attribute_info_count Code属性表的attribute属性个数

00 01 00 10 00 11 00 02 00 09 00 00

00 3E 00 02 00 02 00 00 00 06 2A 2B B5 00 02 B1

00 00 00 02 00 0A 00 00 00 0A 00 02 00 00 00 15

00 05 00 16 00 0B 00 00 00 16 00 02 00 00 00 06

00 0C 00 0D 00 00 00 00 00 06 00 05 00 06 00 01

00 12 00 00 00 05 01 00 05 00 00

A)Code_info的第一个属性表之lineNumberTable

attribute_name_index:0A 指向我们的常量池10的位置

#10 = Utf8 LineNumberTable

00 01 00 10 00 11 00 02 00 09 00 00

00 3E 00 02 00 02 00 00 00 06 2A 2B B5 00 02 B1

00 00 00 02 00 0A 00 00 00 0A 00 02 00 00 00 15

00 05 00 16 00 0B 00 00 00 16 00 02 00 00 00 06

00 0C 00 0D 00 00 00 00 00 06 00 05 00 06 00 01

00 12 00 00 00 05 01 00 05 00 00

attribute_length:占用四个字节 00 00 00 0A(10字节)

表示后面字节是我们的具体的属性

00 01 00 10 00 11 00 02 00 09 00 00

00 3E 00 02 00 02 00 00 00 06 2A 2B B5 00 02 B1

00 00 00 02 00 0A 00 00 00 0A 00 02 00 00 00 15

00 05 00 16 00 0B 00 00 00 16 00 02 00 00 00 06

00 0C 00 0D 00 00 00 00 00 06 00 05 00 06 00 01

00 12 00 00 00 05 01 00 05 00 00

line_number_table_length:占用二个字节 表示2对映射

00 01 00 10 00 11 00 02 00 09 00 00

00 3E 00 02 00 02 00 00 00 06 2A 2B B5 00 02 B1

00 00 00 02 00 0A 00 00 00 0A 00 02 00 00 00 15

00 05 00 16 00 0B 00 00 00 16 00 02 00 00 00 06

00 0C 00 0D 00 00 00 00 00 06 00 05 00 06 00 01

00 12 00 00 00 05 01 00 05 00 00

line_number_info存在二对映射

00 01 00 10 00 11 00 02 00 09 00 00

00 3E 00 02 00 02 00 00 00 06 2A 2B B5 00 02 B1

00 00 00 02 00 0A 00 00 00 0A 00 02 00 00 00 15

00 05 00 16 00 0B 00 00 00 16 00 02 00 00 00 06

00 0C 00 0D 00 00 00 00 00 06 00 05 00 06 00 01

00 12 00 00 00 05 01 00 05 00 00

指令码 00 映射源码 00 15(21)行

指令码05 映射源码00 16(22行)

B)Code_info的第二个属性表之LocalVariableTable

00 01 00 10 00 11 00 02 00 09 00 00

00 3E 00 02 00 02 00 00 00 06 2A 2B B5 00 02 B1

00 00 00 02 00 0A 00 00 00 0A 00 02 00 00 00 15

00 05 00 16 00 0B 00 00 00 16 00 02 00 00 00 06

00 0C 00 0D 00 00 00 00 00 06 00 05 00 06 00 01

00 12 00 00 00 05 01 00 05 00 00

attribute_name_index 00 0B指向我们的常量池11的位置

#11 = Utf8 LocalVariableTable

attribute_length表示属性的长度,后面的22个字节都是我们的属性类容

00 01 00 10 00 11 00 02 00 09 00 00

00 3E 00 02 00 02 00 00 00 06 2A 2B B5 00 02 B1

00 00 00 02 00 0A 00 00 00 0A 00 02 00 00 00 15

00 05 00 16 00 0B 00 00 00 16 00 02 00 00 00 06

00 0C 00 0D 00 00 00 00 00 06 00 05 00 06 00 01

00 12 00 00 00 05 01 00 05 00 00

local_variable_table_length 00 02(表示有二个本地变量表)

00 01 00 10 00 11 00 02 00 09 00 00

00 3E 00 02 00 02 00 00 00 06 2A 2B B5 00 02 B1

00 00 00 02 00 0A 00 00 00 0A 00 02 00 00 00 15

00 05 00 16 00 0B 00 00 00 16 00 02 00 00 00 06

00 0C 00 0D 00 00 00 00 00 06 00 05 00 06 00 01

00 12 00 00 00 05 01 00 05 00 00

Local_variale_info的变量表结构

第一个变量表:

00 01 00 10 00 11 00 02 00 09 00 00

00 3E 00 02 00 02 00 00 00 06 2A 2B B5 00 02 B1

00 00 00 02 00 0A 00 00 00 0A 00 02 00 00 00 15

00 05 00 16 00 0B 00 00 00 16 00 02 00 00 00 06

00 0C 00 0D 00 00 00 00 00 06 00 05 00 06 00 01

00 12 00 00 00 05 01 00 05 00 00

"start_pc":"u2(00 00 )->desc:这个局部变量的生命周期开始的字节码偏移量",

"length:":"u2(00 06)->作用范围覆盖的长度为6",

"name_index":"u2(00 0c)->字段的名称索引指向常量池12的位置 this",

"desc_index":"u2(00 0D)局部变量的描述符号索引->指向#13的位置Lcom/tuling/smlz/jvm/classbyatecode/TulingByteCode;",

"index":"u2(00 00)->desc:index是这个局部变量在栈帧局部变量表中Slot的位置"

第二个变量表:

00 01 00 10 00 11 00 02 00 09 00 00

00 3E 00 02 00 02 00 00 00 06 2A 2B B5 00 02 B1

00 00 00 02 00 0A 00 00 00 0A 00 02 00 00 00 15

00 05 00 16 00 0B 00 00 00 16 00 02 00 00 00 06

00 0C 00 0D 00 00 00 00 00 06 00 05 00 06 00 01

00 12 00 00 00 05 01 00 05 00 00

"start_pc":"u2(00 00 )->desc:这个局部变量的生命周期开始的字节码偏移量",

"length:":"u2(00 06)->作用范围覆盖的长度为6",

"name_index":"u2(00 05)->字段的名称索引指向常量池5的位置 userName",

"desc_index":"u2(00 06)局部变量的描述符号索引->指向#6的位置 Ljava/lang/String;",

"index":"u2(00 01)->desc:index是这个局部变量在栈帧局部变量表中Slot的1位置"

B)Code_info的第二个属性表之MethodParameters方法参数属性表

00 01 00 10 00 11 00 02 00 09 00 00

00 3E 00 02 00 02 00 00 00 06 2A 2B B5 00 02 B1

00 00 00 02 00 0A 00 00 00 0A 00 02 00 00 00 15

00 05 00 16 00 0B 00 00 00 16 00 02 00 00 00 06

00 0C 00 0D 00 00 00 00 00 06 00 05 00 06 00 01

00 12 00 00 00 05 01 00 05 00 00

结构体:

{
  "attribute_name_index":"u2(00 12)表示该属性的名称指向常量池#18的位置:MethodParameters",
  "attribute_length":"u4(00 00 00 05 )->desc:属性的长度5",
  "parameter_count":"u1(01)->desc参数的个数1个",
  "parameter_name_index":"u2(00 05)->desc:指向第五个常量池的常量userName",
  "ACC_FLAG":"U2(00 00 )->desc:表示任何权限都可以访问"
}

最后一部分:class文件的属性

00 01 00 13 00 00 00 02 00 14

"attribute_count(class文件的属性)":"u2(00 01)只有一个属性"

属性结构体:

{
  "attribute_name_index":"u2(00 13) 指向常量池中#19 值为 SourceFile",
  "attribute_length":"u4(00 00 00 02) 表示属性接下来的长度为2",
  "sourceFile_index":"u2(00 14) 表示源文件的索引指向常量池20的位置:TulingByteCode.java"
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2033312.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

经典大语言模型解读(1):BERT——基于双向Transformer的预训练语言模型

论文&#xff1a;BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding 前言 BERT&#xff08;Bidirectional Encoder Representation from Transformer&#xff09;是Google于2019年提出的预训练语言模型。与寻常的Transformer架构不同&#…

eval和长度限制

目录 源码 解决方案 方法一 方法二 方法三 源码 <?php $param $_REQUEST[param]; if(strlen($param)<17 && stripos($param,eval) false && stripos($param,assert) false) {eval($param); } ?> 限制条件&#xff1a; 传入的参数长度不能…

Go语言+Vue3开发前后端后台管理系统实战 用户管理的前端界面和表结构分析

首页&#xff1a; 用户管理界面&#xff1a; 到这一步以后来看一下后端代码的表结构是如何设计的&#xff1a; 后端代码中&#xff0c;使用的操作MySQL的技术是gorm&#xff1a; gorm.io/gorm v1.25.5其中&#xff0c;用户表的定义位置如下&#xff1a; 此时的完整代码如…

C++虚函数习题

#include <iostream>using namespace std;class Animal { public:Animal() {}virtual void perform()0; };class Lion:public Animal { public:Lion() {}void perform(){cout << "狮子会吃小朋友&#xff01;&#xff01;&#xff01;快跑&#xff01;&#x…

设计模式(1)创建型模式和结构型模式

1、目标 本文的主要目标是学习创建型模式和结构型模式&#xff0c;并分别代码实现每种设计模式 2、创建型模式 2.1 单例模式&#xff08;singleton&#xff09; 单例模式是创建一个对象保证只有这个类的唯一实例&#xff0c;单例模式分为饿汉式和懒汉式&#xff0c;饿汉式是…

IP问题总结

IP基础知识 IP 在 TCP/IP 参考模型中处于第三层&#xff0c;也就是⽹络层。 ⽹络层的主要作⽤是&#xff1a;实现主机与主机之间的通信&#xff0c;也叫点对点&#xff08;end to end&#xff09;通信。 1.⽹络层与数据链路层有什么关系呢&#xff1f; 其实很容易区分&#…

eNSP 华为浮动路由

R1&#xff1a; <Huawei>system-view [Huawei]sysname R1 [R1]int g0/0/0 [R1-GigabitEthernet0/0/0]ip add 172.16.1.1 24 [R1-GigabitEthernet0/0/0]int g0/0/1 [R1-GigabitEthernet0/0/1]ip add 10.10.1.1 24 [R1-GigabitEthernet0/0/1]quit [R1]vlan 10 //e口是…

使用docker搭建aria2-pro+ariang并在alist中配置

一、安装aria2-pro 1.创建映射目录 # 配置目录 mkdir -p /usr/local/docker/aria2/config # 下载目录 mkdir -p /share_root/download-aria22.创建容器 docker run -d \--name aria2-pro \--restart unless-stopped \--log-opt max-size1m \--network host \-e PUID$UID \-e …

【秋招笔试】8.12-4399秋招(第一套)-三语言题解

🍭 大家好这里是 春秋招笔试突围,一起备战大厂笔试 💻 ACM金牌团队🏅️ | 多次AK大厂笔试 | 编程一对一辅导 ✨ 本系列打算持续跟新 春秋招笔试题 👏 感谢大家的订阅➕ 和 喜欢💗 和 手里的小花花🌸 ✨ 笔试合集传送们 -> 🧷春秋招笔试合集 🍒 本专栏已收…

全网最详细HAProxy入门小知识

目录 一. 负载均衡 负载均衡的意义&#xff1a; 负载均衡的类型&#xff1a; 二. HAProxy 简介 HAProxy 的特点&#xff1a; 社区版和企业版&#xff1a; 三. HAProxy 的安装和服务信息 1、实验环境 1&#xff09;安装并配置 Nginx 2&#xff09;在客户端测试 2、安装…

【项目实战】C++视频共享点播系统

目录 一、项目介绍 1.1 对视频共享点播系统的认识 1.2服务端程序负责功能 1.3 服务端功能模块划分 1.4 项目界面演示 1.5预备知识 二.环境搭建 2.1 安装 Jsoncpp 库 2.1.1 使用jsoncpp 2.2 引入httplib库 2.2.1 安装Git&#xff08;如果你的系统尚未安装Git&#xf…

基于Hadoop的共享单车分布式存储与计算

文章目录 有需要本项目的代码或文档以及全部资源&#xff0c;或者部署调试可以私信博主项目介绍研究背景研究目的和意义国内外研究现状总体研究思路数据可视化每文一语 有需要本项目的代码或文档以及全部资源&#xff0c;或者部署调试可以私信博主 项目介绍 共享单车的普及带…

Elasticsearch:使用 ES|QL 进行地理空间搜索

作者&#xff1a;来自 Elastic Craig Taverner 多年来&#xff0c;Elasticsearch 一直具有强大的地理空间搜索和分析功能&#xff0c;但其 API 与典型的 GIS 用户习惯的 API 截然不同。在过去的一年中&#xff0c;我们添加了 ES|QL 查询语言&#xff0c;这是一种管道查询语言&a…

React原理之React整体渲染流程

前置知识&#xff1a;深度优先搜索(DFS)、Fiber 节点 在上一篇 React原理篇之 React 整体架构解读中&#xff0c;提到了 Fiber 架构中的几个核心概念&#xff1a; Scheduler&#xff08;调度器&#xff09;&#xff1a;根据任务的优先级安排任务执行顺序。Reconciler&#xff…

CUDA-MODE 第一课课后实战(下)

我的课程笔记&#xff0c;欢迎关注&#xff1a;https://github.com/BBuf/how-to-optim-algorithm-in-cuda/tree/master/cuda-mode CUDA-MODE 第一课课后实战&#xff08;下&#xff09; Nsight Compute Profile结果分析 继续对Nsight Compute的Profile结果进行分析&#xff0…

PyQT 串口改动每次点开时更新串口信息

class MainWindow(QWidget, Ui_Form):def __init__(self):super().__init__(parentNone)self.setupUi(self)self.comboBox.installEventFilter(self) # 加载事件过滤器self.comboBox.addItems(get_ports())def eventFilter(self, obj, event): # 定义事件过滤器if isinstance(o…

前端容器化部署:解决重启容器时的静态资源丢失问题

文章目录 什么是前端容器化&#xff1f;重启容器时静态资源丢失的问题解决静态资源丢失的方案1. 使用持久化卷创建和挂载卷使用Docker Compose定义卷 2. 使用对象存储将静态资源上传到对象存储 3. 使用构建时持久化使用CI/CD管道 4. 使用动态加载和缓存使用浏览器缓存使用服务端…

Java 8日期时间API革新:从Date到LocalDate、LocalTime与LocalDateTime的转型与优势解析

文章目录 前言一、基础介绍1.Date2.LocalDate3.LocalTime4.LocalDateTime 二、区别三、推荐场景四、推荐原因总结 前言 在Java的发展历程中&#xff0c;日期和时间的处理一直是开发者们关注的焦点。从早期的java.util.Date类到java.util.Calendar接口&#xff0c;虽然为日期时间…

Linux从0到1——进程池

Linux从0到1——进程池 1. 进程池的概念2. 进程池实现思路3. 进程池的代码实现3.1 创建管道&#xff0c;创建子进程3.2 封装任务3.3 Work接口3.4 发送任务3.5 回收资源&#xff0c;关闭管道&#xff08;重点&#xff09;3.6 改造CreatChannels接口 4. 完整代码 1. 进程池的概念…

数据结构面试-核心概念-问题理解

目录 1.数据结构及其分类 2.时间复杂度与空间复杂度及大O表示法 3.循环队列及其判断队空和队满的方法 4.栈与队列在计算机系统中的应用 5.串的模式匹配算法 6.线索二叉树、二叉搜索树、平衡二叉树 7.哈夫曼树与哈夫曼编码 8.DFS与BFS 9.最小生成树及其构建算法 10.最短…