jvm signature 属性_深入理解JVM-java字节码文件结构剖析(练习解读字节码)

public class MyTest2 {

String str = "Welcome";

private int x = 5;

public static Integer in = 10;

public static void main(String[] args) {

MyTest2 myTest2 = new MyTest2();

myTest2.setX(8);

in =20;

}

public void setX(int x) {

this.x = x;

}

}

javap -verbose jvm.bytecode.MyTest2

Classfile /Users/luozhiyun/Documents/work/jvm_lecture/target/classes/jvm/bytecode/MyTest2.class

Last modified Mar 16, 2019; size 823 bytes

MD5 checksum 2e0c9064f75aa1f5a5057f17e228387f

Compiled from "MyTest2.java"

public class jvm.bytecode.MyTest2

minor version: 0

major version: 52

flags: ACC_PUBLIC, ACC_SUPER

Constant pool:

#1 = Methodref #10.#34 // java/lang/Object."":()V

#2 = String #35 // Welcome

#3 = Fieldref #5.#36 // jvm/bytecode/MyTest2.str:Ljava/lang/String;

#4 = Fieldref #5.#37 // jvm/bytecode/MyTest2.x:I

#5 = Class #38 // jvm/bytecode/MyTest2

#6 = Methodref #5.#34 // jvm/bytecode/MyTest2."":()V

#7 = Methodref #5.#39 // jvm/bytecode/MyTest2.setX:(I)V

#8 = Methodref #40.#41 // java/lang/Integer.valueOf:(I)Ljava/lang/Integer;

#9 = Fieldref #5.#42 // jvm/bytecode/MyTest2.in:Ljava/lang/Integer;

#10 = Class #43 // java/lang/Object

#11 = Utf8 str

#12 = Utf8 Ljava/lang/String;

#13 = Utf8 x

#14 = Utf8 I

#15 = Utf8 in

#16 = Utf8 Ljava/lang/Integer;

#17 = Utf8

#18 = Utf8 ()V

#19 = Utf8 Code

#20 = Utf8 LineNumberTable

#21 = Utf8 LocalVariableTable

#22 = Utf8 this

#23 = Utf8 Ljvm/bytecode/MyTest2;

#24 = Utf8 main

#25 = Utf8 ([Ljava/lang/String;)V

#26 = Utf8 args

#27 = Utf8 [Ljava/lang/String;

#28 = Utf8 myTest2

#29 = Utf8 setX

#30 = Utf8 (I)V

#31 = Utf8

#32 = Utf8 SourceFile

#33 = Utf8 MyTest2.java

#34 = NameAndType #17:#18 // "":()V

#35 = Utf8 Welcome

#36 = NameAndType #11:#12 // str:Ljava/lang/String;

#37 = NameAndType #13:#14 // x:I

#38 = Utf8 jvm/bytecode/MyTest2

#39 = NameAndType #29:#30 // setX:(I)V

#40 = Class #44 // java/lang/Integer

#41 = NameAndType #45:#46 // valueOf:(I)Ljava/lang/Integer;

#42 = NameAndType #15:#16 // in:Ljava/lang/Integer;

#43 = Utf8 java/lang/Object

#44 = Utf8 java/lang/Integer

#45 = Utf8 valueOf

#46 = Utf8 (I)Ljava/lang/Integer;

{

java.lang.String str;

descriptor: Ljava/lang/String;

flags:

public static java.lang.Integer in;

descriptor: Ljava/lang/Integer;

flags: ACC_PUBLIC, ACC_STATIC

public jvm.bytecode.MyTest2();

descriptor: ()V

flags: ACC_PUBLIC

Code:

stack=2, locals=1, args_size=1

0: aload_0

1: invokespecial #1 // Method java/lang/Object."":()V

4: aload_0

5: ldc #2 // String Welcome

7: putfield #3 // Field str:Ljava/lang/String;

10: aload_0

11: iconst_5

12: putfield #4 // Field x:I

15: return

LineNumberTable:

line 6: 0

line 7: 4

line 8: 10

LocalVariableTable:

Start Length Slot Name Signature

0 16 0 this Ljvm/bytecode/MyTest2;

public static void main(java.lang.String[]);

descriptor: ([Ljava/lang/String;)V

flags: ACC_PUBLIC, ACC_STATIC

Code:

stack=2, locals=2, args_size=1

0: new #5 // class jvm/bytecode/MyTest2

3: dup

4: invokespecial #6 // Method "":()V

7: astore_1

8: aload_1

9: bipush 8

11: invokevirtual #7 // Method setX:(I)V

14: bipush 20

16: invokestatic #8 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;

19: putstatic #9 // Field in:Ljava/lang/Integer;

22: return

LineNumberTable:

line 11: 0

line 12: 8

line 13: 14

line 14: 22

LocalVariableTable:

Start Length Slot Name Signature

0 23 0 args [Ljava/lang/String;

8 15 1 myTest2 Ljvm/bytecode/MyTest2;

public void setX(int);

descriptor: (I)V

flags: ACC_PUBLIC

Code:

stack=2, locals=2, args_size=2

0: aload_0

1: iload_1

2: putfield #4 // Field x:I

5: return

LineNumberTable:

line 17: 0

line 18: 5

LocalVariableTable:

Start Length Slot Name Signature

0 6 0 this Ljvm/bytecode/MyTest2;

0 6 1 x I

static {};

descriptor: ()V

flags: ACC_STATIC

Code:

stack=1, locals=0, args_size=0

0: bipush 10

2: invokestatic #8 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;

5: putstatic #9 // Field in:Ljava/lang/Integer;

8: return

LineNumberTable:

line 9: 0

}

SourceFile: "MyTest2.java"

字节码

cafe babe 0000 0034 002f 0a00 0a00 2208

0023 0900 0500 2409 0005 0025 0700 260a

0005 0022 0a00 0500 270a 0028 0029 0900

0500 2a07 002b 0100 0373 7472 0100 124c

6a61 7661 2f6c 616e 672f 5374 7269 6e67

3b01 0001 7801 0001 4901 0002 696e 0100

134c 6a61 7661 2f6c 616e 672f 496e 7465

6765 723b 0100 063c 696e 6974 3e01 0003

2829 5601 0004 436f 6465 0100 0f4c 696e

654e 756d 6265 7254 6162 6c65 0100 124c

6f63 616c 5661 7269 6162 6c65 5461 626c

6501 0004 7468 6973 0100 164c 6a76 6d2f

6279 7465 636f 6465 2f4d 7954 6573 7432

3b01 0004 6d61 696e 0100 1628 5b4c 6a61

7661 2f6c 616e 672f 5374 7269 6e67 3b29

5601 0004 6172 6773 0100 135b 4c6a 6176

612f 6c61 6e67 2f53 7472 696e 673b 0100

076d 7954 6573 7432 0100 0473 6574 5801

0004 2849 2956 0100 083c 636c 696e 6974

3e01 000a 536f 7572 6365 4669 6c65 0100

0c4d 7954 6573 7432 2e6a 6176 610c 0011

0012 0100 0757 656c 636f 6d65 0c00 0b00

0c0c 000d 000e 0100 146a 766d 2f62 7974

6563 6f64 652f 4d79 5465 7374 320c 001d

001e 0700 2c0c 002d 002e 0c00 0f00 1001

0010 6a61 7661 2f6c 616e 672f 4f62 6a65

6374 0100 116a 6176 612f 6c61 6e67 2f49

6e74 6567 6572 0100 0776 616c 7565 4f66

0100 1628 4929 4c6a 6176 612f 6c61 6e67

2f49 6e74 6567 6572 3b00 2100 0500 0a00

0000 0300 0000 0b00 0c00 0000 0200 0d00

0e00 0000 0900 0f00 1000 0000 0400 0100

1100 1200 0100 1300 0000 4200 0200 0100

0000 102a b700 012a 1202 b500 032a 08b5

0004 b100 0000 0200 1400 0000 0e00 0300

0000 0600 0400 0700 0a00 0800 1500 0000

0c00 0100 0000 1000 1600 1700 0000 0900

1800 1900 0100 1300 0000 5700 0200 0200

0000 17bb 0005 59b7 0006 4c2b 1008 b600

0710 14b8 0008 b300 09b1 0000 0002 0014

0000 0012 0004 0000 000b 0008 000c 000e

000d 0016 000e 0015 0000 0016 0002 0000

0017 001a 001b 0000 0008 000f 001c 0017

0001 0001 001d 001e 0001 0013 0000 003e

0002 0002 0000 0006 2a1b b500 04b1 0000

0002 0014 0000 000a 0002 0000 0011 0005

0012 0015 0000 0016 0002 0000 0006 0016

0017 0000 0000 0006 000d 000e 0001 0008

001f 0012 0001 0013 0000 0021 0001 0000

0000 0009 100a b800 08b3 0009 b100 0000

0100 1400 0000 0600 0100 0000 0900 0100

2000 0000 0200 21

字节码解读

cafe babe 魔数

00 00 00 34 魔数之后的4个字节为版本信息,前两个字节表示minor version(次版本号),后两个字节表示major version(主版本号)

00 2f content pool 为47表示有46个常量

0a 代表值为10 Methodref_info 这个常量

00 0a 代表constant_class_info 索引为#10

00 22代表constant_nameAndType_info索引为#34

08 代表String_info

00 23 代表索引#35

09 代表Fieldref

00 05 代表constant_class_info 索引为#5

00 24 代表constant_nameAndType_info索引为#36

09 代表Fieldref

00 05 代表constant_class_info 索引为#5

00 25 代表constant_nameAndType_info索引为#37

07 代表class_info

00 26 代表权限定名索引 #38

0a 代表Methodref_info

00 05 代表constant_class_info 索引为#5

00 22 代表constant_nameAndType_info索引为#34

0a 代表Methodref_info

00 05 代表constant_class_info 索引为#5

00 27 代表constant_nameAndType_info索引为#39

0a 代表Methodref_info

00 28 代表constant_class_info 索引为#40

00 29 代表constant_nameAndType_info索引为#41

09 代表Fieldref

00 05 代表constant_class_info 索引为#5

00 2a 代表constant_nameAndType_info索引为#42

07 代表class_info

00 2b 代表权限定名索引 #38

01 代表utf8(acsii码转换可以去(http://www.ab126.com/goju/1711.html#ecms)查看)

00 03 代表长度为3

73 74 72 代表str

01 代表utf8

00 12 代表长度为18

4c 6a 61 76 61 2f 6c 61 6e 67 2f 53 74 72 69 6e 67 3b

表示 L j a v a / l a n g / S t r i n g ;

01 代表utf8

00 01 代表长度为1

78 代表x

01 代表utf8

00 01 代表长度为1

49 代表l

01 代表utf8

00 02 代表长度为2

69 6e 代表in

01 代表utf8

00 13 代表长度为19

4c 6a 61 76 61 2f 6c 61 6e 67 2f 49 6e 74 65 67 65 72 3b

代表:L j a v a / l a n g / I n t e g e r ;

01 代表utf8

00 06 代表长度为6

3c 69 6e 69 74 3e

代表:< i n i t >

01 代表utf8

00 03 代表长度为3

28 29 56 代表:( ) V

01 代表utf8

00 04 代表长度为4

43 6f 64 65 代表:code

01 代表utf8

00 0f 代表长度为15

4c 69 6e 65 4e 75 6d 62 65 72 54 61 62 6c 65

代表:L i n e N u m b e r T a b l e

01 代表utf8

00 12 代表长度为18

4c 6f 63 61 6c 56 61 72 69 61 62 6c 65 54 61 62 6c 65

代表:LocalVariableTable

01 代表utf8

00 04 代表长度为4

74 68 69 73 代表:this

01 代表utf8

00 16 代表长度为22

4c 6a 76 6d 2f 62 79 74 65 63 6f 64 65 2f 4d 79 54 65 73 74 32 3b

代表:L j v m / b y t e c o d e / M y T e s t 2 ;

01 代表utf8

00 04 代表长度为4

6d 61 69 6e 代表:main

01 代表utf8

00 16 代表长度为22

28 5b 4c 6a 61 76 61 2f 6c 61 6e 67 2f 53 74 72 69 6e 67 3b 29 56

代表:( [ L j a v a / l a n g / S t r i n g ; ) V

01 代表utf8

00 04 代表长度为4

61 72 67 73 代表:a r g s

01 代表utf8

00 13 代表长度为19

5b 4c 6a 61 76 61 2f 6c 61 6e 67 2f 53 74 72 69 6e 67 3b

代表: [Ljava/lang/String;

01 代表utf8

00 07 代表长度为7

6d 79 54 65 73 74 32 代表:myTest2

01 代表utf8

00 04 代表长度为4

73 65 74 58 代表:setX

01 代表utf8

00 04 代表长度为4

28 49 29 56 代表:(I)V

01 代表utf8

00 08 代表长度为8

3c 63 6c 69 6e 69 74 3e 代表:

01 代表utf8

00 0a 代表长度为10

53 6f 75 72 63 65 46 69 6c 65 代表:SourceFile

01 代表utf8

00 0c 代表长度为12

4d 7954 6573 7432 2e6a 6176 61 代表:MyTest2.java

0c 代表:nameAndType_info

0011 代表:字段或方法名常量项描述符索引 #17

0012 代表:字段或方法名修饰符常量项索引 #18

01 代表utf8

00 07 代表长度为7

57 656c 636f 6d65 代表:Welcome

0c 代表:nameAndType_info

00 0b 代表:字段或方法名常量项描述符索引 #11

00 0c 代表:字段或方法名修饰符常量项索引 #12

0c 代表:nameAndType_info

00 0d 代表:字段或方法名常量项描述符索引 #13

00 0e 代表:字段或方法名修饰符常量项索引 #14

01 代表utf8

00 14 代表长度为20

6a 766d 2f62 7974 6563 6f64 652f 4d79 5465 7374 32

代表:jvm/bytecode/MyTest2

0c 代表:nameAndType_info

001d 代表:字段或方法名常量项描述符索引 #16+13=29

001e 代表:字段或方法名修饰符常量项索引 #16+14=30

07 代表:class_info

00 2c 限定名常量索引 #16*2+12=44

0c 代表:nameAndType_info

00 2d 代表:字段或方法名常量项描述符索引 #32+13=45

00 2e 代表:字段或方法名修饰符常量项索引 #32+ 14=46

0c 代表:nameAndType_info

00 0f 代表:字段或方法名常量项描述符索引 #15

00 10 代表:字段或方法名修饰符常量项索引 #16

01 代表utf8

00 10 代表长度为16

6a61 7661 2f6c 616e 672f 4f62 6a65 6374

代表:java/lang/Object

01 代表utf8

00 11 代表长度为17

6a 6176 612f 6c61 6e67 2f49 6e74 6567 6572

代表:java/lang/Integer

01 代表utf8

00 07 代表长度为7

76 616c 7565 4f66 代表:valueOf

01 代表utf8

00 16 代表长度为22

28 4929 4c6a 6176 612f 6c61 6e67 2f49 6e74 6567 6572 3b

代表:(I)Ljava/lang/Integer;

00 21 Access flag 表示ACC_PUBLIC 与ACC_SUPER取的并集

00 05 This Class Name 表示的一个索引指的是常量池第5个常量

00 0a This Super Name 表示的一个索引指的是常量池第10个常量

00 00 表示没有实现接口

Fields

00 03 表示属性的数量,表示有3个字段

00 00 表示修饰符access_flag 表示没有修饰符

00 0b name_index 名字的索引#11 str

00 0c descriptor_index 描述符的索引 #12 Ljava/lang/String;

00 00 表示attributes_count为0,也就没有attributes_info

00 02 表示修饰符access_flag 表示private

00 0d name_index 名字的索引#13 x

00 0e descriptor_index 描述符的索引 #14 i

00 00 表示attributes_count为0,也就没有attributes_info

00 09 表示修饰符access_flag 表示public static

00 0f name_index 名字的索引#15 in

00 10 descriptor_index 描述符的索引 #16 Ljava/lang/Integer;

00 00 表示attributes_count为0,也就没有attributes_info

Method

00 04 代表有4个方法,包含了自动生成的默认构造器

00 01 代表是一个public的方法

00 11 代表是name_index #17

00 12 代表是descriptor_index #18 ()V

00 01 代表是attribute_count,有一个属性

method attribute

00 13 代表属性名的索引attribute_name_index #19 Code

00 00 00 42 attribute_length 66个字节长度

00 02 max_stack

00 01 max_local 局部变量最大值

00 00 00 10 code_length 方法的代码长度 16个字节

2a b700 012a 1202 b500 032a 08b5 0004 b1

实际上就是对应着下面的助记符

2a -> aload_0

b7 -> invokespecial 00 01 lang/Object."":()V

12 -> ldc(从常量池加载一个常量) 02 #2 Welcome

b5 -> putfield 00 03 #3 jvm/bytecode/MyTest2.str

08 -> iconst_5

b1 -> return

exception

00 00

attributes

00 02 attribute_count; 表示有两个属性

00 14 属性的索引 #20 LineNumberTable

00 00 00 0e attribute_length 14个字节

00 0300 0000 0600 0400 0700 0a00 08

00 03 表示有三对两两映射偏移量

00 00 -> 00 06 表示偏移量为0映射到行号为6

00 04 -> 00 07 表示偏移量为4映射到行号为7

00 0a -> 00 08 表示偏移量为10映射到行号为8

00 15 第21个属性的索引 #21 LocalVariableTable

00 0000 0c 表示LocalVariableTable所占的字节长度

00 0100 0000 1000 1600 1700 00

00 01 局部变量的个数

00 00局部变量开始的位置

00 10 局部变量结束的位置

00 16 局部变量索引 #22 this

00 17 索引 #23 Ljvm/bytecode/MyTest2;

00 00 用来做校验检查的

第二个方法:

00 09 表示public static

00 18 代表是name_index #24 main

00 19 代表是descriptor_index #25 ([Ljava/lang/String;)V

00 01 代表是attribute_count,有一个属性

method attribute

00 13 代表属性名的索引attribute_name_index #19 code

00 0000 57 attribute_length 87个字节长度

00 02 max_stack

00 02 max_local 局部变量最大值

00 0000 17 code_length 方法的代码长度 23个字节

bb 0005 59b7 0006 4c2b 1008 b600 0710 14b8 0008 b300 09b1

实际上就是对应着下面的助记符

bb -> new index: 00 05 jvm/bytecode/MyTest2

59 -> dup Duplicate the top operand stack value

b7 -> invokespecial index: 00 06 jvm/bytecode/MyTest2."":()V

4c -> astore_1 Storereferenceinto local variable

2b -> aload_1

10 -> bipush

08 -> iconst_5

b6 -> invokevirtual index:00 07 jvm/bytecode/MyTest2.setX:(I)V

10 -> bipush

14 -> ldc2_w Push long or double from run-time constant pool index:b8 00 java/lang/Integer

b8 -> invokestatic. index: 0008 java/lang/Integer.valueOf:(I)Ljava/lang/Integer;

b3 -> putstatic index: 00 09 jvm/bytecode/MyTest2.in:Ljava/lang/Integer;

b1 -> return

exception

00 00

attributes

00 02 attribute_count; 表示有两个属性

00 14 属性的索引 #20 LineNumberTable

0000 0012 attribute_length 18个字节

0004 0000 000b 0008 000c 000e 000d 0016 000e

00 04 表示有4对两两映射偏移量

0000 000b 表示偏移量为0映射到行号为11

0008 000c 表示偏移量为8映射到行号为12

000e 000d 表示偏移量为14映射到行号为13

0016 000e 表示偏移量为22映射到行号为14

00 15 第二个属性的索引 #21 LocalVariableTable

0000 0016 表示LocalVariableTable所占的字节长度 22

0002 0000 0017 001a 001b 0000 0008 000f 001c 0017 0001

00 02 局部变量的个数

00 00局部变量1开始的位置

00 17 局部变量1长度 23

00 1a 局部变量1 索引 #26

00 1b 局部变量1 描述符索引 #27 [Ljava/lang/String;

00 00 第一个索引结束

00 08 局部变量2开始的位置

00 0f 局部变量1长度 15

00 1c 局部变量1 索引 #28 myTest2

00 17 局部变量1 描述符索引 #23 Ljvm/bytecode/MyTest2;

00 01 第二个索引结束

第三个方法:

0001 public

001d 表示索引#29 setX

001e 表示索引#30 (I)V

0001 代表是attribute_count,有一个属性

0013 代表属性名的索引attribute_name_index code

0000 003e code_length 方法的代码长度 62个字节

00 02 max_stack

00 02 max_local

00 00 00 06 code_length 方法的代码长度 6个字节

2a1b b500 04b1

2a 1b b5 00 02 b1

2a -> aload_0

1b -> iload_1

b5 -> putfield

00 02 表示第二常量

b1 -> return

attributes

00 02 attribute_count; 表示有两个属性

0014 索引指向第20个常量 LineNumberTable

0000 000a attribute_length 10个字节

0002 0000 0011 0005 0012

00 02 表示有两个对应关系

00 00 00 11 偏移量为0的对应的是11行

00 05 00 12 偏移量为5的对应的是12行

00 15 第二个属性的索引 #21 LocalVariableTable

00 00 00 16 表示LocalVariableTable所占的字节长度 22个

0002 0000 0006 0016 0017 0000 0000 0006 000d 000e 0001

00 02 局部变量的个数

00 00局部变量开始的位置

00 06 局部变量结束的位置

00 16 局部变量索引的位置 #22 this

00 17 局部变量索引的位置 #23 Ljava/lang/Integer;

00 00局部变量开始的位置

00 06 局部变量结束的位置

00 0d 局部变量索引的位置 #13 x

00 0e 局部变量索引的位置 #14 I

第四个方法:

0008 : 代表public

001f : 表示索引#31

0012 : 表示索引#18 ()V

00 01: 代表是attribute_count,有一个属性

0013 代表属性名的索引attribute_name_index code

0000 0021 code_length 方法的代码长度 33个字节

0001 max_stack

0000 max_local

0000 0009 code_length 方法的代码长度9个字节

100a b800 08b3 0009 b1

10 -> bipush 0a : 10

b8 -> invokestatic 00 08. #8 java/lang/Integer.valueOf:(I)Ljava/lang/Integer;

b3 -> putstatic 0009. #9 jvm/bytecode/MyTest2.in:Ljava/lang/Integer;

b1 -> return

attributes

00 01 attribute_count; 表示有1个属性

00 14 索引指向第20个常量 LineNumberTable

00 0000 06 attribute_length 6个字节

00 0100 0000 09

00 01 表示有1个对应关系

00 00 00 09 偏移量为0的对应的是9行

Attributes

00 01

00 20 索引 #32 sourceFile

00 0000 02 源文件的长度

00 21 #33 MyTest2.java

java学习笔记/jvm

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值