参考文献
-
class
文件格式: https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html -
od
命令 -
javap
命令
Hello.java
Hello.java
文件的内容如下
public class Hello {
public static void main(String[] args) {
System.out.println("Hello world");
}
}
Hello.java
被编译成 Hello.class
后,可以被虚拟机执行。
class
文件有自己的格式,细节可以参考 https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html
由于 Hello.java
的内容比较简单,所以我就以 Hello.class
的内容为例,来简单解释一下 class
文件的格式。
Hello.class
借助如下命令,我们可以将 Hello.java
编译成 Hello.class
。
javac Hello.java
借助如下命令,我们可以查看 Hello.class
文件的内容
od -t x1 Hello.class
上述命令的完整输出结果如下
0000000 ca fe ba be 00 00 00 34 00 1d 0a 00 06 00 0f 09
0000020 00 10 00 11 08 00 12 0a 00 13 00 14 07 00 15 07
0000040 00 16 01 00 06 3c 69 6e 69 74 3e 01 00 03 28 29
0000060 56 01 00 04 43 6f 64 65 01 00 0f 4c 69 6e 65 4e
0000100 75 6d 62 65 72 54 61 62 6c 65 01 00 04 6d 61 69
0000120 6e 01 00 16 28 5b 4c 6a 61 76 61 2f 6c 61 6e 67
0000140 2f 53 74 72 69 6e 67 3b 29 56 01 00 0a 53 6f 75
0000160 72 63 65 46 69 6c 65 01 00 0a 48 65 6c 6c 6f 2e
0000200 6a 61 76 61 0c 00 07 00 08 07 00 17 0c 00 18 00
0000220 19 01 00 0b 48 65 6c 6c 6f 20 77 6f 72 6c 64 07
0000240 00 1a 0c 00 1b 00 1c 01 00 05 48 65 6c 6c 6f 01
0000260 00 10 6a 61 76 61 2f 6c 61 6e 67 2f 4f 62 6a 65
0000300 63 74 01 00 10 6a 61 76 61 2f 6c 61 6e 67 2f 53
0000320 79 73 74 65 6d 01 00 03 6f 75 74 01 00 15 4c 6a
0000340 61 76 61 2f 69 6f 2f 50 72 69 6e 74 53 74 72 65
0000360 61 6d 3b 01 00 13 6a 61 76 61 2f 69 6f 2f 50 72
0000400 69 6e 74 53 74 72 65 61 6d 01 00 07 70 72 69 6e
0000420 74 6c 6e 01 00 15 28 4c 6a 61 76 61 2f 6c 61 6e
0000440 67 2f 53 74 72 69 6e 67 3b 29 56 00 21 00 05 00
0000460 06 00 00 00 00 00 02 00 01 00 07 00 08 00 01 00
0000500 09 00 00 00 1d 00 01 00 01 00 00 00 05 2a b7 00
0000520 01 b1 00 00 00 01 00 0a 00 00 00 06 00 01 00 00
0000540 00 01 00 09 00 0b 00 0c 00 01 00 09 00 00 00 25
0000560 00 02 00 01 00 00 00 09 b2 00 02 12 03 b6 00 04
0000600 b1 00 00 00 01 00 0a 00 00 00 0a 00 02 00 00 00
0000620 03 00 08 00 04 00 01 00 0d 00 00 00 02 00 0e
0000637
class
文件的内容可以分为如下几部分
名称 | 参考译名 | 长度(单位:字节) |
---|---|---|
magic | 魔数 | 4 |
minor_version | 次版本号 | 2 |
major_version | 主版本号 | 2 |
constant_pool_count | 常量池大小? | 2 |
constant_pool | 常量池 | 不固定 |
access_flags | 访问标志 | 2 |
this_class | 类索引 | 2 |
super_class | 父类索引 | 2 |
interfaces_count | 接口数量 | 2 |
interfaces | ? | interfaces_count * 2 |
fields_count | 2 | |
fields | 不固定 | |
methods_count | 2 | |
methods | 不固定 | |
attributes_count | 2 | |
attributes | 不固定 |
下面我们来逐个分析
magic(魔数)
前四个字节的值为 0xCAFEBABE

minor_version(次版本号)
Hello.class
中的次版本号为 0

major_version(主版本号)
Hello.class
中的主版本号为十进制的 52
(如果写成十六进制,就是 0x34
)

constant_pool_count
值为 0x1d
(用十进制表示29)

constant_pool(常量池)
#1
常量池中的 #1
元素共有5个字节,即 0x0a0006000f

第一个字节为
0x0a
表示 CONSTANT_Methodref
其结构为
CONSTANT_Methodref_info {
u1 tag;
u2 class_index;
u2 name_and_type_index;
}
具体值如下
tag=0x0a
class_index=0x0006
name_and_type_index=0x000f
网友评论