class文件的格式等理论概念网上很多,不再赘述,下面是针对一个class文件实例进行”翻译“。
源文件
package com.sss.jvm.unclassified;
public class SimpleUser {
public static final int TYPE = 1;
private int id;
private String name;
public int getId(){
return id;
}
public void setId(int id) throws IllegalStateException{
try {
this.id = id;
} catch (Exception e) {
e.printStackTrace();
}
}
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
}
class文件
cafe babe 0000 0034 002f 0a00 0700 2609
0006 0027 0700 280a 0003 0029 0900 0600
2a07 002b 0700 2c01 0004 5459 5045 0100
0149 0100 0d43 6f6e 7374 616e 7456 616c
7565 0300 0000 0101 0002 6964 0100 046e
616d 6501 0012 4c6a 6176 612f 6c61 6e67
2f53 7472 696e 673b 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 254c
636f 6d2f 7373 732f 6a76 6d2f 756e 636c
6173 7369 6669 6564 2f53 696d 706c 6555
7365 723b 0100 0567 6574 4964 0100 0328
2949 0100 0573 6574 4964 0100 0428 4929
5601 0001 6501 0015 4c6a 6176 612f 6c61
6e67 2f45 7863 6570 7469 6f6e 3b01 000d
5374 6163 6b4d 6170 5461 626c 6507 0028
0100 0a45 7863 6570 7469 6f6e 7307 002d
0100 0767 6574 4e61 6d65 0100 1428 294c
6a61 7661 2f6c 616e 672f 5374 7269 6e67
3b01 0007 7365 744e 616d 6501 0015 284c
6a61 7661 2f6c 616e 672f 5374 7269 6e67
3b29 5601 000a 536f 7572 6365 4669 6c65
0100 0f53 696d 706c 6555 7365 722e 6a61
7661 0c00 0f00 100c 000c 0009 0100 136a
6176 612f 6c61 6e67 2f45 7863 6570 7469
6f6e 0c00 2e00 100c 000d 000e 0100 2363
6f6d 2f73 7373 2f6a 766d 2f75 6e63 6c61
7373 6966 6965 642f 5369 6d70 6c65 5573
6572 0100 106a 6176 612f 6c61 6e67 2f4f
626a 6563 7401 001f 6a61 7661 2f6c 616e
672f 496c 6c65 6761 6c53 7461 7465 4578
6365 7074 696f 6e01 000f 7072 696e 7453
7461 636b 5472 6163 6500 2100 0600 0700
0000 0300 1900 0800 0900 0100 0a00 0000
0200 0b00 0200 0c00 0900 0000 0200 0d00
0e00 0000 0500 0100 0f00 1000 0100 1100
0000 2f00 0100 0100 0000 052a b700 01b1
0000 0002 0012 0000 0006 0001 0000 0007
0013 0000 000c 0001 0000 0005 0014 0015
0000 0001 0016 0017 0001 0011 0000 002f
0001 0001 0000 0005 2ab4 0002 ac00 0000
0200 1200 0000 0600 0100 0000 0e00 1300
0000 0c00 0100 0000 0500 1400 1500 0000
0100 1800 1900 0200 1100 0000 7100 0200
0300 0000 0e2a 1bb5 0002 a700 084d 2cb6
0004 b100 0100 0000 0500 0800 0300 0300
1200 0000 1600 0500 0000 1300 0500 1600
0800 1400 0900 1500 0d00 1700 1300 0000
2000 0300 0900 0400 1a00 1b00 0200 0000
0e00 1400 1500 0000 0000 0e00 0c00 0900
0100 1c00 0000 0700 0248 0700 1d04 001e
0000 0004 0001 001f 0001 0020 0021 0001
0011 0000 002f 0001 0001 0000 0005 2ab4
0005 b000 0000 0200 1200 0000 0600 0100
0000 1a00 1300 0000 0c00 0100 0000 0500
1400 1500 0000 0100 2200 2300 0100 1100
0000 3e00 0200 0200 0000 062a 2bb5 0005
b100 0000 0200 1200 0000 0a00 0200 0000
1e00 0500 1f00 1300 0000 1600 0200 0000
0600 1400 1500 0000 0000 0600 0d00 0e00
0100 0100 2400 0000 0200 25
逐行解析
常量id | 待分析的十六进制 | 转换十进制/可视化 | 翻译 |
---|---|---|---|
cafe babe | 魔数,固定值,“咖啡宝贝” | ||
0000 0034 | 0 52 | 低版本0,高版本52,也就是jdk1.8 | |
002f | 47 | 常量值有47-1=46个元素,第0个空缺 | |
#1 | 0a | 10 | CONSTANT_Methodref_info |
00 07 | 7 | 指向CONSTANT_Class_info的索引 | |
00 26 | 38 | 指向CONSTANT_NameAndType_info的索引 | |
#2 | 09 | 9 | CONSTANT_Fieldref_info |
00 06 | 6 | 指向CONSTANT_Class_info的索引 | |
00 27 | 39 | 指向CONSTANT_NameAndType_info的索引 | |
#3 | 07 | 7 | CONSTANT_Class_info |
00 28 | 40 | 指向#40 | |
#4 | 0a | 10 | CONSTANT_Methodref_info |
00 03 | 3 | 指向CONSTANT_Class_info的索引 | |
00 29 | 41 | 指向CONSTANT_NameAndType_info的索引 | |
#5 | 09 | 9 | CONSTANT_Fieldref_info |
00 06 | 6 | 指向CONSTANT_Class_info的索引 | |
00 2a | 42 | 指向CONSTANT_NameAndType_info的索引 | |
#6 | 07 | 7 | CONSTANT_Class_info |
00 2b | 43 | 指向常量43的索引 | |
#7 | 07 | 7 | CONSTANT_Class_info |
00 2c | 44 | 指向#44 | |
#8 | 01 | 1 | CONSTANT_Utf8_info |
00 04 | 4 | UTF8编码的字符串,长度为4 | |
54 59 50 45 | TYPE | TYPE | |
#9 | 01 | 1 | CONSTANT_Utf8_info |
00 01 | 1 | UTF8编码的字符串,长度为1 | |
49 | I | I | |
#10 | 01 | 1 | CONSTANT_Utf8_info |
00 0d | 13 | UTF8编码的字符串,长度为13 | |
43 6f 6e 73 74 61 6e 74 56 61 6c 75 65 | ConstantValue | ConstantValue | |
#11 | 03 | 3 | CONSTANT_Intege_info |
00 00 00 01 | 1 | 1 | |
#12 | 01 | 1 | CONSTANT_Utf8_info |
00 02 | 2 | UTF8编码的字符串,长度为2 | |
69 64 | id | id | |
#13 | 01 | 1 | CONSTANT_Utf8_info |
00 04 | 4 | UTF8编码的字符串,长度为4 | |
6e 616d 65 | name | name | |
#14 | 01 | 1 | CONSTANT_Utf8_info |
00 12 | 18 | UTF8编码的字符串,长度为12 | |
4c6a 6176 612f 6c61 6e67 2f53 7472 696e 673b | Ljava/lang/String; | Ljava/lang/String; | |
#15 | 01 | 1 | CONSTANT_Utf8_info |
00 06 | 6 | UTF8编码的字符串,长度为6 | |
3c 696e 6974 3e | |||
#16 | 01 | 1 | CONSTANT_Utf8_info |
00 03 | 3 | UTF8编码的字符串,长度为3 | |
2829 56 | ()V | ()V | |
#17 | 01 | 1 | CONSTANT_Utf8_info |
0004 | 4 | UTF8编码的字符串,长度为4 | |
436f 6465 | Code | Code | |
#18 | 01 | 1 | CONSTANT_Utf8_info |
00 0f | 15 | UTF8编码的字符串,长度为15 | |
4c 696e 654e 756d 6265 7254 6162 6c65 | LineNumberTable | LineNumberTable | |
#19 | 01 | 1 | CONSTANT_Utf8_info |
00 12 | 18 | UTF8编码的字符串,长度为18 | |
4c 6f63 616c 5661 7269 6162 6c65 5461 626c 65 | LocalVariableTable | LocalVariableTable | |
#20 | 01 | 1 | CONSTANT_Utf8_info |
00 04 | 4 | UTF8编码的字符串,长度为4 | |
7468 6973 | this | this | |
#21 | 01 | 1 | CONSTANT_Utf8_info |
00 25 | 37 | UTF8编码的字符串,长度为37 | |
54c 636f 6d2f 7373 732f 6a76 6d2f 756e 636c 6173 7369 6669 6564 2f53 696d 706c 6555 7365 723b | Lcom/sss/jvm/unclassified/SimpleUser; | Lcom/sss/jvm/unclassified/SimpleUser; | |
#22 | 01 | 1 | CONSTANT_Utf8_info |
00 05 | 5 | UTF8编码的字符串,长度为4 | |
67 6574 4964 | getId | getId | |
#23 | 01 | 1 | CONSTANT_Utf8_info |
00 03 | 3 | UTF8编码的字符串,长度为3 | |
28 2949 | ()I | ()I | |
#24 | 01 | 1 | CONSTANT_Utf8_info |
00 05 | 5 | UTF8编码的字符串,长度为3 | |
73 6574 4964 | setId | setId | |
#25 | 01 | 1 | CONSTANT_Utf8_info |
00 04 | 4 | UTF8编码的字符串,长度为4 | |
28 4929 56 | (I)V | (I)V | |
#26 | 01 | 1 | CONSTANT_Utf8_info |
00 01 | 1 | UTF8编码的字符串,长度为1 | |
65 | e | e | |
#27 | 01 | 1 | CONSTANT_Utf8_info |
00 15 | 21 | UTF8编码的字符串,长度为21 | |
4c6a 6176 612f 6c61 6e67 2f45 7863 6570 7469 6f6e 3b | Ljava/lang/Exception; | Ljava/lang/Exception; | |
#28 | 01 | 1 | CONSTANT_Utf8_info |
00 0d | 13 | UTF8编码的字符串,长度为13 | |
5374 6163 6b4d 6170 5461 626c 65 | StackMapTable | StackMapTable | |
#29 | 07 | 7 | CONSTANT_Class_info |
00 28 | 40 | 指向#40 | |
#30 | 01 | 1 | CONSTANT_Utf8_info |
00 0a | 10 | UTF8编码的字符串,长度为10 | |
45 7863 6570 7469 6f6e 73 | Exceptions | Exceptions | |
#31 | 07 | 7 | CONSTANT_Class_info |
00 2d | 45 | 指向#45 | |
#32 | 01 | 1 | CONSTANT_Utf8_info |
00 07 | 7 | UTF8编码的字符串,长度为7 | |
67 6574 4e61 6d65 | getName | getName | |
#33 | 01 | 1 | CONSTANT_Utf8_info |
00 14 | 20 | UTF8编码的字符串,长度为20 | |
28 294c 6a61 7661 2f6c 616e 672f 5374 7269 6e67 3b | ()Ljava/lang/String; | ()Ljava/lang/String; | |
#34 | 01 | 1 | CONSTANT_Utf8_info |
00 07 | 7 | UTF8编码的字符串,长度为7 | |
7365 744e 616d 65 | setName | setName | |
#35 | 01 | 1 | CONSTANT_Utf8_info |
00 15 | 21 | UTF8编码的字符串,长度为21 | |
284c 6a61 7661 2f6c 616e 672f 5374 7269 6e67 3b29 56 | (Ljava/lang/String;)V | (Ljava/lang/String;)V | |
#36 | 01 | 1 | CONSTANT_Utf8_info |
00 0a | 10 | UTF8编码的字符串,长度为10 | |
536f 7572 6365 4669 6c65 | SourceFile | SourceFile | |
#37 | 01 | 1 | CONSTANT_Utf8_info |
00 0f | 15 | UTF8编码的字符串,长度为15 | |
53 696d 706c 6555 7365 722e 6a61 7661 | SimpleUser.java | SimpleUser.java | |
#38 | 0c | 12 | CONSTANT_NameAndType_info |
00 0f | 15 | 指向#15 | |
00 10 | 16 | 指向#16 | |
#39 | 0c | 12 | CONSTANT_NameAndType_info |
00 0c | 12 | 指向#12 | |
00 08 | 9 | 指向#9 | |
#40 | 01 | 1 | CONSTANT_Utf8_info |
00 13 | 19 | UTF8编码的字符串,长度为15 | |
6a 6176 612f 6c61 6e67 2f45 7863 6570 7469 6f6e | java/lang/Exception | java/lang/Exception | |
#41 | 0c | 12 | CONSTANT_NameAndType_info |
00 2e | 46 | 指向#46 | |
00 10 | 16 | 指向#16 | |
#42 | 0c | 12 | CONSTANT_NameAndType_info |
00 0d | 13 | 指向#13 | |
00 0e | 14 | 指向#14 | |
#43 | 01 | 1 | CONSTANT_Utf8_info |
00 23 | 35 | UTF8编码的字符串,长度为35 | |
63 6f6d 2f73 7373 2f6a 766d 2f75 6e63 6c61 7373 6966 6965 642f 5369 6d70 6c65 5573 6572 | com/sss/jvm/unclassified/SimpleUser | com/sss/jvm/unclassified/SimpleUser | |
#44 | 01 | 1 | CONSTANT_Utf8_info |
00 10 | 16 | UTF8编码的字符串,长度为16 | |
6a 6176 612f 6c61 6e67 2f4f 626a 6563 74 | java/lang/Object | java/lang/Object | |
#45 | 01 | 1 | CONSTANT_Utf8_info |
00 1f | 31 | UTF8编码的字符串,长度为31 | |
6a61 7661 2f6c 616e 672f 496c 6c65 6761 6c53 7461 7465 4578 6365 7074 696f 6e | java/lang/IllegalStateException | java/lang/IllegalStateException | |
#46 | 01 | 1 | CONSTANT_Utf8_info |
00 0f | 15 | UTF8编码的字符串,长度为15 | |
7072 696e 7453 7461 636b 5472 6163 65 | printStackTrace | printStackTrace | |
00 21 | 00 21是0020和0001的并集,表示ACC_PUBLIC和ACC_SUPER | 类的访问修饰符 | |
00 06 | 指向#6,即com/sss/jvm/unclassified/SimpleUser | 类名 | |
00 07 | 指向#7,即java/lang/Object | 父类名 | |
#接口 | 00 00 | 接口数量0 | 接口数量0 |
#成员变量 | 00 03 | 成员变量3个 | 成员变量3个 |
成员变量1 | 00 19 | access_flags | public + final + static |
00 08 | name_index | TYPE | |
00 09 | descriptor_index | I (int的缩写) | |
00 01 | attributes_count | 1 | |
javap查看字节码验证
Last modified 2020-7-26; size 1003 bytes
MD5 checksum 649990cb1874364be61948448f5976d9
Compiled from "SimpleUser.java"
public class com.sss.jvm.unclassified.SimpleUser
minor version: 0
major version: 52
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 = Methodref #7.#38 // java/lang/Object."<init>":()V
#2 = Fieldref #6.#39 // com/sss/jvm/unclassified/SimpleUser.id:I
#3 = Class #40 // java/lang/Exception
#4 = Methodref #3.#41 // java/lang/Exception.printStackTrace:()V
#5 = Fieldref #6.#42 // com/sss/jvm/unclassified/SimpleUser.name:Ljava/lang/String;
#6 = Class #43 // com/sss/jvm/unclassified/SimpleUser
#7 = Class #44 // java/lang/Object
#8 = Utf8 TYPE
#9 = Utf8 I
#10 = Utf8 ConstantValue
#11 = Integer 1
#12 = Utf8 id
#13 = Utf8 name
#14 = Utf8 Ljava/lang/String;
#15 = Utf8 <init>
#16 = Utf8 ()V
#17 = Utf8 Code
#18 = Utf8 LineNumberTable
#19 = Utf8 LocalVariableTable
#20 = Utf8 this
#21 = Utf8 Lcom/sss/jvm/unclassified/SimpleUser;
#22 = Utf8 getId
#23 = Utf8 ()I
#24 = Utf8 setId
#25 = Utf8 (I)V
#26 = Utf8 e
#27 = Utf8 Ljava/lang/Exception;
#28 = Utf8 StackMapTable
#29 = Class #40 // java/lang/Exception
#30 = Utf8 Exceptions
#31 = Class #45 // java/lang/IllegalStateException
#32 = Utf8 getName
#33 = Utf8 ()Ljava/lang/String;
#34 = Utf8 setName
#35 = Utf8 (Ljava/lang/String;)V
#36 = Utf8 SourceFile
#37 = Utf8 SimpleUser.java
#38 = NameAndType #15:#16 // "<init>":()V
#39 = NameAndType #12:#9 // id:I
#40 = Utf8 java/lang/Exception
#41 = NameAndType #46:#16 // printStackTrace:()V
#42 = NameAndType #13:#14 // name:Ljava/lang/String;
#43 = Utf8 com/sss/jvm/unclassified/SimpleUser
#44 = Utf8 java/lang/Object
#45 = Utf8 java/lang/IllegalStateException
#46 = Utf8 printStackTrace
{
public static final int TYPE;
descriptor: I
flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL
ConstantValue: int 1
private int id;
descriptor: I
flags: ACC_PRIVATE
private java.lang.String name;
descriptor: Ljava/lang/String;
flags: ACC_PRIVATE
public com.sss.jvm.unclassified.SimpleUser();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
LineNumberTable:
line 7: 0
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this Lcom/sss/jvm/unclassified/SimpleUser;
public int getId();
descriptor: ()I
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: getfield #2 // Field id:I
4: ireturn
LineNumberTable:
line 14: 0
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this Lcom/sss/jvm/unclassified/SimpleUser;
public void setId(int) throws java.lang.IllegalStateException;
descriptor: (I)V
flags: ACC_PUBLIC
Code:
stack=2, locals=3, args_size=2
0: aload_0
1: iload_1
2: putfield #2 // Field id:I
5: goto 13
8: astore_2
9: aload_2
10: invokevirtual #4 // Method java/lang/Exception.printStackTrace:()V
13: return
Exception table:
from to target type
0 5 8 Class java/lang/Exception
LineNumberTable:
line 19: 0
line 22: 5
line 20: 8
line 21: 9
line 23: 13
LocalVariableTable:
Start Length Slot Name Signature
9 4 2 e Ljava/lang/Exception;
0 14 0 this Lcom/sss/jvm/unclassified/SimpleUser;
0 14 1 id I
StackMapTable: number_of_entries = 2
frame_type = 72 /* same_locals_1_stack_item */
stack = [ class java/lang/Exception ]
frame_type = 4 /* same */
Exceptions:
throws java.lang.IllegalStateException
public java.lang.String getName();
descriptor: ()Ljava/lang/String;
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: getfield #5 // Field name:Ljava/lang/String;
4: areturn
LineNumberTable:
line 26: 0
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this Lcom/sss/jvm/unclassified/SimpleUser;
public void setName(java.lang.String);
descriptor: (Ljava/lang/String;)V
flags: ACC_PUBLIC
Code:
stack=2, locals=2, args_size=2
0: aload_0
1: aload_1
2: putfield #5 // Field name:Ljava/lang/String;
5: return
LineNumberTable:
line 30: 0
line 31: 5
LocalVariableTable:
Start Length Slot Name Signature
0 6 0 this Lcom/sss/jvm/unclassified/SimpleUser;
0 6 1 name Ljava/lang/String;
}
SourceFile: "SimpleUser.java"
Process finished with exit code 0