[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文件

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

CA FE BA BE magic u4
minor_version

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

第一个是标志位,07代表CONSTANT_Class_info:

name_index需要读取两个字节,如上上图白框
07 CONSTANT_Class_info 07同时也是tag
00 02 name_index:引用2号,记为#2
然后来解读一下2号(记为#2),

第一个标志位01代表CONSTANT_Utf8_info,0018就是代表0x18=24个字节的字符串,就是接下来24个字节都是这个字符串的引用com/lee/he11o/HelloWorld
:

也就是说,CONSTANT_Class_info
引用的是#2,为com/lee/he11o/HelloWorld
。
后面的解读都是这样操作即可。
借用工具解读
用肉眼一个一个解读就过于重复操作了,jdk提供了工具帮我们解读这个class文件,就是javap。

可以简单看看,#1对应的是class信息,引用的是#2,#2对应的是utf8,对应的字符串是com/lee/hello/HelloWorld
。正好就是我们上面解读的信息。
网友评论