[Java]深入理解Java Class文件格式(一)
Java字节码(.class文件)格式详解(一)
编写一个文件
package com.lee.hello;
public class HelloWorld {
public static void main(String[] args) {
System.out.println("hello world!");
}
}
用UE打开编译好的.class文件
image.png
class文件中的数据项
总体格式表:
类型
名称
数量
u4
magic
1
u2
minor_version
1
u2
major_version
1
u2
constant_pool_count
1
cp_info
constant_pool
constant_pool_count - 1
u2
access_flags
1
u2
this_class
1
u2
super_class
1
u2
interfaces_count
1
u2
interfaces
interfaces_count
u2
fields_count
1
field_info
fields
fields_count
u2
methods_count
1
method_info
methods
methods_count
u2
attribute_count
1
attribute_info
attributes
attributes_count
class文件中的信息是一项一项排列的, 每项数据都有它的固定长度, 有的占一个字节, 有的占两个字节, 还有的占四个字节或8个字节, 数据项的不同长度分别用u1, u2, u4, u8表示, 分别表示一种数据项在class文件中占据1个字节, 2个字节, 4个字节和8个字节。 可以把u1, u2, u3, u4看做class文件数据项的“类型” 。
解读
magic
image.png
CA FE BA BE magic u4
minor_version
image.png
00 00 minor_version u2
major_version
00 34 major_version
0x34 = 52,对应的是java 8的版本
constant_pool_count
00 10 constant_pool_count
代表接下来有0x10=16-1=15个常量。
cp_info = constant_pool_count - 1
第一个cp_info
image.png
第一个是标志位,07代表CONSTANT_Class_info:
image.png
name_index需要读取两个字节,如上上图白框
07 CONSTANT_Class_info 07同时也是tag
00 02 name_index:引用2号,记为#2
然后来解读一下2号(记为#2),
image.png
第一个标志位01代表CONSTANT_Utf8_info,0018就是代表0x18=24个字节的字符串,就是接下来24个字节都是这个字符串的引用com/lee/he11o/HelloWorld
:
image.png
也就是说,CONSTANT_Class_info
引用的是#2,为com/lee/he11o/HelloWorld
。
后面的解读都是这样操作即可。
借用工具解读
用肉眼一个一个解读就过于重复操作了,jdk提供了工具帮我们解读这个class文件,就是javap。
image.png
可以简单看看,#1对应的是class信息,引用的是#2,#2对应的是utf8,对应的字符串是com/lee/hello/HelloWorld
。正好就是我们上面解读的信息。