JVM学习笔记10-Java字节码文件结构剖析示例

    xiaoxiao2025-08-04  21

    结合JVM学习笔记8-Java字节码文件结构剖析说明,对如下的字节码信息进行解析

    行号 字节码信息 000 CA FE BA BE 00 00 00 34 00 1C 0A 00 04 00 18 09 .......4........ 010 00 03 00 19 07 00 1A 07 00 1B 01 00 01 61 01 00 .............a.. 020 01 49 01 00 06 3C 69 6E 69 74 3E 01 00 03 28 29 .I...<init>...() 030 56 01 00 04 43 6F 64 65 01 00 0F 4C 69 6E 65 4E V...Code...LineN 040 75 6D 62 65 72 54 61 62 6C 65 01 00 12 4C 6F 63 umberTable...Loc 050 61 6C 56 61 72 69 61 62 6C 65 54 61 62 6C 65 01 alVariableTable. 060 00 04 74 68 69 73 01 00 1B 4C 6D 61 69 6E 2F 6A ..this...Lmain/j 070 76 6D 2F 62 79 74 65 63 6F 64 65 2F 4D 79 54 65 vm/bytecode/MyTe 080 73 74 31 3B 01 00 04 67 65 74 41 01 00 03 28 29 st1;...getA...() 090 49 01 00 04 73 65 74 41 01 00 04 28 49 29 56 01 I...setA...(I)V. 0A0 00 04 6D 61 69 6E 01 00 16 28 5B 4C 6A 61 76 61 ..main...([Ljava 0B0 2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29 56 01 /lang/String;)V. 0C0 00 04 61 72 67 73 01 00 13 5B 4C 6A 61 76 61 2F ..args...[Ljava/ 0D0 6C 61 6E 67 2F 53 74 72 69 6E 67 3B 01 00 0A 53 lang/String;...S 0E0 6F 75 72 63 65 46 69 6C 65 01 00 0C 4D 79 54 65 ourceFile...MyTe 0F0 73 74 31 2E 6A 61 76 61 0C 00 07 00 08 0C 00 05 st1.java........ 100 00 06 01 00 19 6D 61 69 6E 2F 6A 76 6D 2F 62 79 .....main/jvm/by 110 74 65 63 6F 64 65 2F 4D 79 54 65 73 74 31 01 00 tecode/MyTest1.. 120 10 6A 61 76 61 2F 6C 61 6E 67 2F 4F 62 6A 65 63 .java/lang/Objec 130 74 00 21 00 03 00 04 00 00 00 01 00 02 00 05 00 t.!............. 140 06 00 00 00 04 00 01 00 07 00 08 00 01 00 09 00 ................ 150 00 00 38 00 02 00 01 00 00 00 0A 2A B7 00 01 2A ..8........*...* 160 04 B5 00 02 B1 00 00 00 02 00 0A 00 00 00 0A 00 ................ 170 02 00 00 00 08 00 04 00 09 00 0B 00 00 00 0C 00 ................ 180 01 00 00 00 0A 00 0C 00 0D 00 00 00 01 00 0E 00 ................ 190 0F 00 01 00 09 00 00 00 2F 00 01 00 01 00 00 00 ......../....... 1A0 05 2A B4 00 02 AC 00 00 00 02 00 0A 00 00 00 06 .*.............. 1B0 00 01 00 00 00 0C 00 0B 00 00 00 0C 00 01 00 00 ................ 1C0 00 05 00 0C 00 0D 00 00 00 01 00 10 00 11 00 01 ................ 1D0 00 09 00 00 00 3E 00 02 00 02 00 00 00 06 2A 1B .....>........*. 1E0 B5 00 02 B1 00 00 00 02 00 0A 00 00 00 0A 00 02 ................ 1F0 00 00 00 10 00 05 00 11 00 0B 00 00 00 16 00 02 ................ 200 00 00 00 06 00 0C 00 0D 00 00 00 00 00 06 00 05 ................ 210 00 06 00 01 00 09 00 12 00 13 00 01 00 09 00 00 ................ 220 00 2B 00 00 00 01 00 00 00 01 B1 00 00 00 02 00 .+.............. 230 0A 00 00 00 06 00 01 00 00 00 15 00 0B 00 00 00 ................ 240 0C 00 01 00 00 00 01 00 14 00 15 00 00 00 01 00 ................ 250 16 00 00 00 02 00 17 .......

    通过上述信息,可得到如下信息

    **加粗样式** 表2. 字节码.class文件结构 长度子元素长度描述信息示例(16进制)说明是否为固定值4字节-magic number---魔数CA FE BA BE16进制无是4字节2字节 minor version—次版本号00 0016进制无-2字节major version—主版本号00 3416进制—5210进制对应JDK版本为1.8-不固定2字节constant pool size00 1C16进制—2810进制常量池数组中元素的个数=28-1=27-不固定 constant pool group 常量池组 见表1 0A 00 04 00 1816进制 从表1对应可知OA对应类型为CONSTANT_Methodref_info且占5个字节0A16进制—1010进制 1-1200 0416进制—410进制表示对应的符合引用为400 1816进制—2410进制表示对应的符合引用为24 09 00 03 00 1916进制 从表1对应可知09对应类型为CONSTANT_Fieldref_info 且占5个字节 0916进制—910进制 1-1200 0316进制—310进制 表示对应的符号引用为3 00 1916进制—2510进制 表示对应的符号引用为25 07 00 1A16进制 从表1对应可知07对应类型为CONSTANT_class_info 且占3个字节 0716进制—710进制1-1200 1A16进制—2610进制 表示对应的符号引用为26 07 00 1B16进制 从表1对应可知07对应类型为CONSTANT_class_info 且占3个字节 0716进制—710进制1-1200 1B16进制—2710进制 表示对应的符号引用为27 01 00 01 6116进制 从表1对应可知01对应类型为CONSTANT_utf8_info 且占4个字节 0116进制—110进制1-1200 0116进制—110进制 UTF-8编码的字符串长度为1个字节 6110进制—9710进制 长度为1的UTF-8编码的字符串,即为a 01 00 01 4916进制 从表1对应可知01对应类型为CONSTANT_utf8_info 且占4个字节 0116进制—110进制1-1200 0116进制—110进制 UTF-8编码的字符串长度为1个字节 4910进制—7310进制 长度为1字节的UTF-8编码的字符串,即为I 01 00 06 3C 69 6E 69 74 3E16进制 从表1对应可知01对应类型为CONSTANT_utf8_info 且占9个字节 0116进制—110进制1-1200 0616进制—610进制 UTF-8编码的字符串长度为6个字节 3C 69 6E 69 74 3E10进制 长度为6字节的UTF-8编码的字符串,即为<init> 01 00 03 28 29 5616进制 从表1对应可知01对应类型为CONSTANT_utf8_info 且占6个字节 0116进制—110进制1-1200 0316进制—310进制 UTF-8编码的字符串长度为3个字节 28 29 5610进制 长度为3字节的UTF-8编码的字符串,即为()V 01 00 04 43 6F 64 6516进制 从表1对应可知01对应类型为CONSTANT_utf8_info 且占7个字节 0116进制—110进制1-1200 0416进制—410进制 UTF-8编码的字符串长度为4个字节 43 6F 64 6516进制 长度为4字节的UTF-8编码的字符串,即为Code 01 00 0F 4C 69 6E 65 4E 75 6D 62 65 72 54 61 62 6C 6516进制 从表1对应可知01对应类型为CONSTANT_utf8_info 且占18个字节 0116进制—110进制1-1200 0F16进制—1510进制 UTF-8编码的字符串长度为15个字节 4C 69 6E 65 4E 75 6D 62 65 72 54 61 62 6C 6516进制 长度为字节的UTF-8编码的字符串,即为LineNumberTable 01 00 12 4C 6F 63 61 6C 56 61 72 69 61 62 6C 65 54 61 62 6C 6516进制 从表1对应可知01对应类型为CONSTANT_utf8_info 且占21个字节 0116进制—110进制1-1200 1216进制—1810进制 UTF-8编码的字符串长度为18个字节 4C 6F 63 61 6C 56 61 72 69 61 62 6C 65 54 61 62 6C 6516进制 长度为18字节的UTF-8编码的字符串,即为LocalVariableTable 01 00 04 74 68 69 7316进制 从表1对应可知01对应类型为CONSTANT_utf8_info 且占7个字节 0116进制—110进制1-1200 0416进制—410进制 UTF-8编码的字符串长度为4个字节 74 68 69 7316进制 长度为18字节的UTF-8编码的字符串,即为this 01 00 1B 4C 6D 61 69 6E 2F 6A 76 6D 2F 62 79 74 65 63 6F 64 65 2F 4D 79 54 65 73 74 31 3B16进制 从表1对应可知01对应类型为CONSTANT_utf8_info 且占30个字节 0116进制—110进制1-1200 1B16进制—2710进制 UTF-8编码的字符串长度为27个字节 4C 6D 61 69 6E 2F 6A 76 6D 2F 62 79 74 65 63 6F 64 65 2F 4D 79 54 65 73 74 31 3B16进制 长度为27字节的UTF-8编码的字符串,即为Lmain/jvm/bytecode/MyTest1; 01 00 04 67 65 74 4116进制 从表1对应可知01对应类型为CONSTANT_utf8_info 且占7个字节 0116进制—110进制1-1200 0416进制—410进制 UTF-8编码的字符串长度为4个字节 67 65 74 4116进制 长度为4字节的UTF-8编码的字符串,即为getA 01 00 03 28 29 4916进制 从表1对应可知01对应类型为CONSTANT_utf8_info 且占6个字节 0116进制—110进制1-1200 0316进制—410进制 UTF-8编码的字符串长度为3个字节 28 29 4916进制 长度为3字节的UTF-8编码的字符串,即为()I 以此类推...... 0C 00 07 00 0816进制 从表1对应可知0C对应类型为CONSTANT_NameAndType_info 且占5个字节 0C16进制—1210进制1-1200 0716进制—710进制 表示对应的符号引用为7 00 0816进制—710进制 表示对应的符号引用为8 0C 00 05 00 0616进制 从表1对应可知0C对应类型为CONSTANT_NameAndType_info 且占5个字节 0C16进制—1210进制1-1200 0516进制—510进制 表示对应的符号引用为5 00 0616进制—610进制 表示对应的符号引用为6 01 00 19 6D 61 69 6E 2F 6A 76 6D 2F 62 79 74 65 63 6F 64 65 2F 4D 79 54 65 73 74 3116进制 从表1对应可知01对应类型为CONSTANT_utf8_info 且占28个字节 0116进制—110进制1-1200 1916进制—2510进制 UTF-8编码的字符串长度为25个字节 6D 61 69 6E 2F 6A 76 6D 2F 62 79 74 65 63 6F 64 65 2F 4D 79 54 65 73 74 3116进制 长度为3字节的UTF-8编码的字符串,即为main/jvm/bytecode/MyTest1 01 00 10 6A 61 76 61 2F 6C 61 6E 67 2F 4F 62 6A 65 63 7416进制 从表1对应可知01对应类型为CONSTANT_utf8_info 且占19个字节 0116进制—110进制1-1200 1016进制—1610进制 UTF-8编码的字符串长度为16个字节 6A 61 76 61 2F 6C 61 6E 67 2F 4F 62 6A 65 63 7416进制 长度为16字节的UTF-8编码的字符串,即为java/lang/Object 2字节access flags—访问标志00 2116进制表示ACC_SUPER ACC_PUBLIC2字节-this class—当前类名00 0316进制—310进制 通过javap -verbose操作文件后输出的信息,其对应的值为main/jvm/bytecode/MyTest12字节-super class—父类名00 0416进制—410进制 通过javap -verbose操作文件后输出的信息,其对应的值为java/lang/Object2字节-interfaces_count—接口个数00 0016进制—010进制 2字节-fields_count—域个数 00 0116进制—110进制 表示域个数为1不固定2字节filed_info—字段表 00 0216进制—210进制 access_flags—域的访问标识 表示ACC_PRIVATE 2字节00 0516进制—510进制name_index—字段名索引表示a2字节00 0616进制—610进制descriptor_index—描述符索引表示I2字节00 0016进制—010进制attribute_count—附加属性个数表示无附加属性2字节-methods_count—方法个数 00 0416进制—410进制 表示方法个数为4不固定2字节method_info—方法表 00 0116进制—110进制 access_flags—域的访问标识 表示ACC_PUBLIC 2字节00 0716进制—710进制name_index—字段名索引表示<init>2字节00 0816进制—810进制descriptor_index—描述符索引表示()V2字节00 0116进制—110进制attribute_count—附加属性个数表示有1个附加属性2字节 attribute_infoattribute_name_index 00 0916进制—910进制 表示Code 4字节attribute_length 00 00 00 3816进制—5610进制 表示Code [CA FE BA BE]---魔数 [00 00]---次版本号 [00 34]---主版本号 [00 1C]--常量池数组中元素的个数 [0A 00 04 00 18]---见表2 [09 00 03 00 19]---见表2 [07 00 1A]---见表2 [07 00 1B]---见表2 [01 00 01 61]---a [01 00 01 49]---I [01 00 06 3C 69 6E 69 74 3E]---<init> [01 00 03 28 29 56]---()V [01 00 04 43 6F 64 65]---Code [01 00 0F 4C 69 6E 65 4E 75 6D 62 65 72 54 61 62 6C 65]---LineNumberTable [01 00 12 4C 6F 63 61 6C 56 61 72 69 61 62 6C 65 54 61 62 6C 65]---LocalVariableTable [01 00 04 74 68 69 73]---this [01 00 1B 4C 6D 61 69 6E 2F 6A 76 6D 2F 62 79 74 65 63 6F 64 65 2F 4D 79 54 65 73 74 31 3B]---Lmain/jvm/bytecode/MyTest1; [01 00 04 67 65 74 41]---getA [01 00 03 28 29 49]---()I [01 00 04 73 65 74 41]---setA [01 00 04 28 49 29 56]---(I)V [01 00 04 6D 61 69 6E]---main [01 00 16 28 5B 4C 6A 61 76 61 2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29 56]---([Ljava/lang/String;)V [01 00 04 61 72 67 73]---args [01 00 13 5B 4C 6A 61 76 61 2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B]---[Ljava/lang/String; [01 00 0A 53 6F 75 72 63 65 46 69 6C 65]---SourceFile [01 00 0C 4D 79 54 65 73 74 31 2E 6A 61 76 61]---MyTest1.java [0C 00 07 00 08]--见表2 [0C 00 05 00 06]--见表2 [01 00 19 6D 61 69 6E 2F 6A 76 6D 2F 62 79 74 65 63 6F 64 65 2F 4D 79 54 65 73 74 31]---main/jvm/bytecode/MyTest1 [01 00 10 6A 61 76 61 2F 6C 61 6E 67 2F 4F 62 6A 65 63 74]---java/lang/Object [00 21]---访问标志 ACC_SUPER和ACC_PUBLIC [00 03]---this class-main/jvm/bytecode/MyTest1 [00 04]---super class-java/lang/Object [00 00]---interfaces_count-接口个数 [00 01]---fields_count-域个数 field_info [ [00 02]---access_flags-域访问标识,ACC_PRIVATE [00 05]---name_index-字段名索引 a [00 06]---descriptor_index-描述符索引 I [00 00]()V ] [00 04]---methods_count-方法个数 method_info [ [00 01]---access_flags-访问标志位 ACC_PUBLIC [00 07]---name_index-字段名索引-<init> [00 08]---descriptor_index-8个常量-()V [00 01]---attribute_count-属性名个数 1 Code_attribute [ [00 09]---attribute_name_index-Code [00 00 00 38]---attribute_length-56 [00 02]---max_stack-2 [00 01]---max_locals-1 [00 00 00 0A]---code_length-10 code[code_length] [ 2A---aload_0(42) B7---invokespecial(183) 00 01---<java/lang/Object.<init>> 2A---aload_0(42) 04---iconst_1 B5---putfield(185) 00 02---<main/jvm/bytecode/MyTest1.a>(12) B1---return(177) ] [00 00]---exception_table_length-0 [00 02]---attributes_count-2 LineNumberTable [ [00 0A]---attribute_name_index-LineNumberTable [00 00 00 0A]---attribute_length-10 [00 02]---line_number_table_length-2 [ 00 00---start_pc-0 00 08---line_number-8 ] [ 00 04---start_pc-4 00 09---line_number-9 ] ] [00 0B]---attribute_name_index-LocalVariableTable [00 00 00 0C]---attribute_length-12 [00 01]---local_variable_table_length-1 [ 00 00---start_pc-0 00 0A---length-10 00 0C---name_index-12(this) 00 0D---descripor_index-13(Lmain/jvm/bytecode/MyTest1;) 00 00---index-0 ] ] [ [00 01]---access_flags-访问标志位 ACC_PUBLIC [00 0E]---name_index(14)-getA [00 0F]---descriptor_index(15)-()I [00 01]---attribute_count(1) [00 09]---attribute_name_index(9)-Code [00 00 00 2F]---attribute_length(47) [00 01]---max_stack(1) [00 01]---max_locals(1) [00 00 00 05---code_length(5) [ 2A---(42)-aload_0 B4---(180)-getfield 00 02---(2)-<main/jvm/bytecode/MyTest1.a> AC---172-ireturn ] [00 00]---exception_table_length(0) [00 02]---attributes_count(2) [00 0A]---attribute_name_index(10)-LineNumberTable [00 00 00 06]---attribute_length(6) [00 01]---line_number_table_length(1) [00 00]---start_pc-0 [00 0C]---line_number(12) [00 0B]---attribute_name_index(11)-LocalVariableTable [00 00 00 0C]---attribute_length(12) [00 01]---local_variable_table_length(1) [00 00]---start_pc(0) [00 05]---length [00 0C]---name_index(12)-this [00 0D]---descripor_index(13)-Lmain/jvm/bytecode/MyTest1; [00 00]---index ] [ [00 01]------access_flags-访问标志位 ACC_PUBLIC [00 10]---name_index(16)-setA [00 11]---descriptor_index(17)-(I)V [00 01]---attribute_count(1) [00 09]attribute_name_index(9)-Code [00 00 00 3E]---attribute_length(62) [00 02]---max_stack(2) [00 02]---max_locals(2) [00 00 00 06]---code_length(6) [ 2A---(42)-aload_0 1B---(27)-iload_1 B5---(185)-putfield 00 02---main/jvm/bytecode/MyTest1.a:I B1---(177)-return ] 00 00---exception_table_length(0) [00 02]---attributes_count(2) [00 0A]---attribute_name_index(10)-LineNumberTable [00 00 00 0A]---attribute_length(10) [00 02]---line_number_table_length(2) [ 00 00--start_pc-0 00 10---line_number(16) ] [ 00 05--start_pc-0 00 11---line_number(17) ] [00 0B]---attribute_name_index(11)-LocalVariableTable [00 00 00 16]---attribute_length(22) [00 02]--local_variable_table_length(2) [ 00 00---start_pc(0) 00 06---length(6) 00 0C---name_index(12)-this 00 0D---descripor_index(13)-Lmain/jvm/bytecode/MyTest1; 00 00---index ] [ 00 00---start_pc(0) 00 06---length(6) 00 05---name_index(5)-a 00 06---descripor_index(6)-I 00 01---index ] ] [ [00 09]---access_flags-访问标志位 ACC_PUBLIC,ACC_STATIC [00 12]---name_index(18)-main [00 13]---descriptor_index(19)-([Ljava/lang/String;)V [00 01]---attribute_count(1) [00 09]---attribute_name_index(9)-Code [00 00 00 2B]---attribute_length(43) [00 00]---max_stack(0) [00 01]---max_locals(1) [00 00 00 01]---code_length(1) [ B1-(177)-return ] [00 00]---exception_table_length [00 02]---attributes_count(2) [00 0A]---attribute_name_index(10)-LineNumberTable [00 00 00 06]---attribute_length(6) [00 01]---line_number_table_length(1) [ 00 00---start_pc 00 15---line_number(22) ] [00 0B]---attribute_name_index(11)-LocalVariableTable [00 00 00 0C]---attribute_length(12) 00 01---local_variable_table_length(1) [ 00 00---start_pc 00 01---length 00 14---name_index(20)-args 00 15---descripor_index(21)-[Ljava/lang/String; 00 00---index ] ] [00 01]---attributes_count(1) [00 16]---attribute_name_index(22)-SourceFile [00 00 00 02]---attribute_length(2) [00 17]---sourcefile_index(23)-MyTest1.java

    通过javap -verbose操作文件后输出的信息如下:

    Classfile /Users/lutingfeng/Documents/idea/jvm_learn/out/production/jvm_learn/main/jvm/bytecode/MyTest1.class Last modified 2019-5-23; size 599 bytes MD5 checksum 6a32f2f9fbd03e43d42bca1fc75fc88d Compiled from "MyTest1.java" public class main.jvm.bytecode.MyTest1 minor version: 0 major version: 52 flags: ACC_PUBLIC, ACC_SUPER Constant pool: #1 = Methodref #4.#24 // java/lang/Object."<init>":()V #2 = Fieldref #3.#25 // main/jvm/bytecode/MyTest1.a:I #3 = Class #26 // main/jvm/bytecode/MyTest1 #4 = Class #27 // java/lang/Object #5 = Utf8 a #6 = Utf8 I #7 = Utf8 <init> #8 = Utf8 ()V #9 = Utf8 Code #10 = Utf8 LineNumberTable #11 = Utf8 LocalVariableTable #12 = Utf8 this #13 = Utf8 Lmain/jvm/bytecode/MyTest1; #14 = Utf8 getA #15 = Utf8 ()I #16 = Utf8 setA #17 = Utf8 (I)V #18 = Utf8 main #19 = Utf8 ([Ljava/lang/String;)V #20 = Utf8 args #21 = Utf8 [Ljava/lang/String; #22 = Utf8 SourceFile #23 = Utf8 MyTest1.java #24 = NameAndType #7:#8 // "<init>":()V #25 = NameAndType #5:#6 // a:I #26 = Utf8 main/jvm/bytecode/MyTest1 #27 = Utf8 java/lang/Object { public main.jvm.bytecode.MyTest1(); descriptor: ()V flags: ACC_PUBLIC Code: stack=2, locals=1, args_size=1 0: aload_0 1: invokespecial #1 // Method java/lang/Object."<init>":()V 4: aload_0 5: iconst_1 6: putfield #2 // Field a:I 9: return LineNumberTable: line 8: 0 line 9: 4 LocalVariableTable: Start Length Slot Name Signature 0 10 0 this Lmain/jvm/bytecode/MyTest1; public int getA(); descriptor: ()I flags: ACC_PUBLIC Code: stack=1, locals=1, args_size=1 0: aload_0 1: getfield #2 // Field a:I 4: ireturn LineNumberTable: line 12: 0 LocalVariableTable: Start Length Slot Name Signature 0 5 0 this Lmain/jvm/bytecode/MyTest1; public void setA(int); descriptor: (I)V flags: ACC_PUBLIC Code: stack=2, locals=2, args_size=2 0: aload_0 1: iload_1 2: putfield #2 // Field a:I 5: return LineNumberTable: line 16: 0 line 17: 5 LocalVariableTable: Start Length Slot Name Signature 0 6 0 this Lmain/jvm/bytecode/MyTest1; 0 6 1 a I public static void main(java.lang.String[]); descriptor: ([Ljava/lang/String;)V flags: ACC_PUBLIC, ACC_STATIC Code: stack=0, locals=1, args_size=1 0: return LineNumberTable: line 21: 0 LocalVariableTable: Start Length Slot Name Signature 0 1 0 args [Ljava/lang/String; } SourceFile: "MyTest1.java"
    最新回复(0)