base - .class文件的结构是什么样的?

141 阅读3分钟

世界上并没有完美的程序,但是我们并不因此而沮丧,因为写程序就是一个不断追求完美的过程。

  1. .class文件是以8字节为单位的紧凑排列的二进制流,对格式有严格的要求
  2. class文件格式稳定,有很好的的向后兼容性。并且JVM不允许执行高版本的class文件
  3. class文件只有两种数据类型:无符号数和表
  4. 无符号数:u1、u2、u4、u8,分别代表1、2、4、8个字节
  5. 表:由多个无符号数或表组和而成
  6. 描述某一类型连续数据时(集合):容量计数器+数据项
  7. 魔数(u4):0xCAFEBABE,用来判断文件类型为class文件
  8. 次版本号(u2)(Minor Version):5、6字节
  9. 主版本号(u2)(Major Version):7、8字节
  10. java主版本号从45开始,JDK1.1 - 45,JDK13 - 57
  11. 常量池:class文件的资源仓库
  12. 常量池容量计数(u2)是从1开始的(其他都是从0)
  13. 常量池有两种类型的常量:字面量和符号引用
  14. 字面量:文本字符串、final常量
  15. 符号引用:
    被模块导出或开放的包
    类和接口的全限定名
    方法的名称和描述符
    方法句柄和方法类型
    动态调用点和动态常量
  16. 对于符号引用,在JVM类加载时才分配内存地址
  17. 常量池中每一个常量都是一个表
  18. 截止JDK13,常量池中分别有17种不同类型的常量
  19. 每个常量表第一位都是tag(u1)标志位,表示常量类型
  20. 访问标志(u2) :类或接口的访问信息
	ACC_PUBLIC
	ACC_FINAL
	ACC_SUPER
	ACC_INTERFACE
	ACC_ABSTRACT
	ACC_SYNTHETIC
	ACC_ANNOTATION
	ACC_ENUM
	ACC_MODULE

access_flags一共有16个标志位,现在使用了其中的9个
其他清零
21. 类索引(u2)、父类索引(u2)、接口索引(u2)集合:确定类的继承关系
类索引 - 类的全限定名
父类索引 - 父类的全限定名
查找全限定名的过程:
索引 -> (常量池)CONSTANT_Class_info -> (常量池)CONSTANT_Utf8_info = 类的全限定名

接口索引 - 实现了哪些接口,从左到右的集合
结构:接口计数器,接口
22. 字段表:静态变量和实例变量
字段表结构

access_flags
name_index
descriptor_index

access_flags

ACC_PUBLIC
ACC_PRIVATE
ACC_PROTECTED
ACC_FINAL
ACC_STATIC
ACC_VOLATILE
ACC_TRANSIENT
ACC_SYNTHETIC
ACC_ENUM

name_index(对常量池的引用):字段简单名称
name_index -> CONSTANT_Utf8_info
descriptor_index(描述符):字段的类型、方法的参数列表和返回值。
描述符表示:

基本数据类型和void都使用一个字母表示:
byte: B
char: C
short: S
int: I
long: J
float: F
double: D
boolean: Z
void: V
对象:L + 类的全限定名
数组:[

描述符实例:

int fun(char[][] chars, int a) {}
([[CI)I

属性表集合 - 存储额外信息

字段表集合中不会列出从父类或父接口中继承的字段
java中字段不支持重载
class文件中只要描述符不同,字段名相同也认为是合法的