1.语言无关性
JVM不直接通过编程语言执行程序,而是通过其他编程语言转换成的.class文件执行程序,这样实现了跨平台
2.文件结构
u1,u2,u4,u8表示1,2,4,8个字节
2.1魔数
Magic
是否是一个java的class文件
,4个字节的长整型,如果不符合图中字符,一定不是java的class文件
2.2版本
能够看出来使用哪个版本的jdk进行编译的
Minor_version小版本
Major_version大版本
2.3常量池
Constant_pool_count常量池的个数
Constant_pool常量池的内容
方法、字段都会依赖常量池的内容。
CONSTANT-utf8
-tag 1 u1
-length u2
-bytes[length] u1
CONSTANT_Integer
-tag 3 u1
-byte u4
CONSTANT_String
-tag 8
-string_index u2(指向utf8字符串字面量的索引)
CONSTANT_NameAndType
-tag 12
-name_index u2(名字,指向utf8)
-descriptor_index u2(描述符类型,指向utf8)
CONSTANT_Class
-tag 7
-name_index u2(名字,指向utf8)
CONSTANT_Fieldref, CONSTANT_Methodref, CONSTANT_InterfaceMethodref
-tag 9, 10, 11
-class_index u2(指向constant_class)方法等是哪个类的
-name_and_type_index u2(指向constant_NameAndType)方法的名字和参数,返回值类型
2.4访问符
Access_flags u2,类的访问标识符
2.5类、超类、接口
This_class类:指向常量池的class
Super_class超类:指向常量池的class
Interfaces_count接口数
Interfaces接口集合
-interface_count个interface u2
-每个接口是指向CONSTANT_class的索引
2.6字段
Fields_count字段数
Fields
-field_count个field_info
Field
-access_flags u2访问标识
-name_index u2名字索引
常量池的引用,表示字段的名字
-desciptor_index u2描述索引
表示字段的类型
-attributes_count u2属性数量
-attribute_info attributes[attributes_count];属性数组中的属性信息
2.7方法
Methods_count方法数
Methods方法
Method_info
-access_flags u2
-name_index u2方法名
-descriptor_index u2 参数和返回值
-attributes_count
-attribute_info attributes[attributes_count];
2.8属性
Attribute_count属性数
Attributes属性
在field和method中,可以有若干个attribute,类文件也有attribute,用于描述一些额外的信息
-attribute_name_index u2-名字,指向常量池utf8
-attribute_length u4长度
-info[attribute_length] u1内容
Attribute本身也可以包含其他attribute
Exception_table_length,异常表到底有多少个异常等着处理
Exceptions属性
-和code属性平级
-表示方法抛出的异常(throws 部分)
0-3,cafebabe,魔数代表Java的class文件,接下来小版本和大版本,然后常量池里有0x0025=37个常量,常量后面开始,每种常量池项目都有一个字节的标志位tag,所以07通过查表可知是class_info类型,其中的0002表示name_index的索引值,即偏移量,指向了敞亮吃的第2项常量。他的标志位tag01,表示utf8类型,001B表示length,说明有27个字节,即后面跟着27个字节内容就是geym/jvm/ch10等
常量池结束之后,接下来是两个字节的访问标志符,有上述源代码可知,该类的修饰符只有public和super,所以他的access_flags值为0x0001|0x0020=0x0021,类索引、父类索引(两者都是全限定类名)和接口索引集合都按顺序排在访问标志之后,类索引和父索引引用两个u2类型的索引值,指向一个constant_class_info,通过constant_class_info可以知道constant_utf8常量中的全限定类名,对于接口索引集合,这里只提供了u2类型的数据为接口计数器,表示有多少个接口。故0x0001,0x0003, 0x0000分别表示类索引为1,父类索引为3,接口集合大小为0;接下来是field_count字段,0x0003表示有三个字段,接下来就是字段的access_flags, 0x0002表示private,name_index0x0005表示指向constant_utf8的字符串为“id”,descriptor_index0x0006表示指向常量池的字符串I,int,即private int id;以此类推;下面就不再阐述了