引言
我们知道,java语言之所以能够跨平台运行,一方面是因为jvm帮助我们屏蔽了操作系统之间的差异性,而另一方面则是class文件的独特性。
程序员编写的文件是.java
文件,而javac
命令能够帮我们将.java文件
编译成.class文件
,那class文件的结构是怎样的?
class类文件结构
一个class文件总共包含以下15个部分
字段名称 | 描述 | 长度 | 备注 |
---|---|---|---|
magic | 唯一标识 | 4 | class文件固定为0xcafebabe |
version | class版本号 | 4 | 包括minor_version和major_version |
constant_pool_count | 常量池数量 | 2 | |
constant_pool[1~constant_pool_count] | 常量池内容 | 无 | constant_pool[0]专用于空指向 |
access_flags | 访问标志 | 2 | |
this_class | 当前类名 | 2 | 当前类的全限定名 |
super_class | 父类名 | 2 | 父类的全限定名 |
interfaces_count | 接口数量 | 2 | |
interfaces[interfaces_count] | 接口内容 | 无 | |
fields_count | 属性数量 | 2 | |
fields[fields_count] | 属性内容 | 无 | |
methods_count | 方法数量 | 2 | |
methods[methods_count] | 方法内容 | 无 | |
attributes_count | 附加属性数量 | 2 | |
attributes[attributes_count] | 附加属性内容 | 无 |
常量池
在常量池中,java总共包含14中不同类型的常量池,如下表
常量名称 | 描述 | 字段tag | 字段2 | 字段3 | 长度(字节) |
---|---|---|---|---|---|
CONSTANT_Utf8_info | uf-8编码的字符串 | 1 | u2 length | ulength bytes[length] | length+3 |
CONSTANT_Integer_info | 整型字面量 | 3 | u4 bytes | 5 | |
CONSTANT_Float_info | 浮点型字面量 | 4 | u4 bytes | 5 | |
CONSTANT_Long_info | 长整型字面量 | 5 | u4 high_bytes | u4 low_bytes | 9 |
CONSTANT_Double_info | 双精度型字面量 | 6 | u4 high_bytes | u4 low_bytes | 9 |
CONSTANT_Class_info | 表示类或接口 | 7 | u2 name_index | 3 | |
CONSTANT_String_info | String类型的常量对象 | 8 | u2 string_index | 3 | |
CONSTANT_Fieldref_info | 字段信息表 | 9 | u2 class_index | u2 name_and_type_index | 5 |
CONSTANT_Methodref_info | 方法 | 10 | u2 class_index | u2 name_and_type_index | 5 |
CONSTANT_InterfaceMethodref_info | 接口方法 | 11 | u2 class_index | u2 name_and_type_index | 5 |
CONSTANT_NameAndType_info | 名称和类型表 | 12 | u2 name_index | u2 descriptor_index | 5 |
CONSTANT MethodHandle_info | 方法句柄表 | 15 | u1 reference_kind | u2 reference_index | 4 |
CONSTANT_MethodType_info | 方法类型表 | 16 | u2 descriptor_index | 3 | |
CONSTANT_InvokeDynamic_info | 动态方法调用点 | 18 | u2 bootstrap_method_attr_index | u2 name_and_type_index | 5 |
访问标志符
实际存储的值通过位运算的形式进行计算最终的访问标志,比如0x0021 = 0x0020 + 0x0001
字段名称 | 值 | 描述 |
---|---|---|
ACC_PUBLIC | 0x0001 | 是否为public类型 |
ACC_FINAL | 0x0010 | 是否为final |
ACC_SUPER | 0x0020 | 该标志必须为真,JDK1.0.2之后编译出来的内容必须为真,指明invokespectial指令使用新语义 |
ACC_INTERFACE | 0x0200 | 是否接口 |
ACC_ABSTRACT | 0x0400 | 接口或抽象类 |
ACC_SYNTHETIC | 0x1000 | 编译器自动生成,非用户代码产生 |
ACC_ANNOTATION | 0x2000 | 是否为注解 |
ACC_ENUM | 0x4000 | 是否为枚举 |
属性、方法
字段名称 | 描述 | 大小 |
---|---|---|
access_flags | 访问符 | 2字节 |
name_index | 名称指向 | 2 |
descriptor_index u2 | 描述指向 | 2 |
attributes_count | 属性长度 | 4 |
attributes | 属性名索引 | 2 |
版权声明:本文为weixin_43660088原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。