概述
只要是Class文件,一定对应着某个有效的类,或者某个接口
但是这个“Class文件”不一定需要定义在文件里,只是一串二进制字节流,包括但不限于这些形式:磁盘文件、网络、数据库、内存、动态生成
Class文件是一组以8个字节为基础单位的二进制流
无符号数属于基本的数据类型,以u1、u2、u4、u8来分别代表1个字节、2个字节、4个字节和8个字节的无符号数
表是由多个无符号数或者其他表作为数据项构成的复合数据类型
所有表的命名都习惯性地以“_info”结尾,表用于描述有层次关系的复合结构的数据
结构
使用魔数替代扩展名进行身份识别
常量池
Class文件里的资源仓库
Class文件结构中与其他项目关联最多的数据
常量池的入口需要放置一项u2类型的数据,从1而不是0开始
将第0项常量空出来是有特殊考虑的,“不引用任何一个常量池项目”的含义,可以把索引值设置为0来表示
只有常量池的容量计数是从1开始,对于其他集合类型,包括接口索引集合、字段表集合、方法表集合等的容量计数都与一般习惯相同,是从0开始。
主要存放两大类常量:
字面量:
接近于Java语言层面的常量概念,如文本字符串、被声明为final的常量值等
符号引用:
属于编译原理方面的概念,主要包括下面几类常量:
被模块导出或者开放的包
类和接口的全限定名
字段的名称和描述符
方法的名称和描述符
方法句柄和方法类型
动态调用点和动态常量
在虚拟机加载Class文件的时候进行动态连接,在Class文件中不会保存各个方法、字段最终在内存中的布局信息
这些字段、方法的符号引用不经过虚拟机在运行期转换的话是无法得到真正的内存入口地址
虚拟机做类加载时,会从常量池获得对应的符号引用,再在类创建时或运行时解析、翻译到具体的内存地址之中。
常量池中每一项常量都是一个表
阅读常量池示例:
访问标志
在常量池结束之后,紧接着的2个字节代表访问标志(access_flags)
用于识别一些类或者接口层次的访问信息
包括:这个Class是类还是接口;是否定义为public类型;是否定义为abstract类型;如果是类的话,是否被声明为final;等等
Class文件是Java虚拟机执行引擎的数据入口
这是我觉得讲的很好的一句话