《深入理解JAVA虚拟机》读书笔记08
第六章 《类文件结构》
Java语言最大的特点是语言无关性,而实现这个的基础是虚拟机和字节码的存储格式,使用Java编译器可以把Java代码编译为存储字节码的Class文件,只要符合虚拟机的运行规范,就可以进行运行。如图所示:
1、Class类文件的结构:
Class文件是一组以8位字节为基础的二进制流,各个数据项严格按照顺序紧密的排列在一起,中间没有添加任何分隔符。这中结构中只有两种数据类型:无符号数和表。
无符号数属于基本的数据类型,以u1、u2、u4、u8来分别代表一个字节、两个字节、四个字节和八个字节的无符号数、无符号数可以用来描述数字、索引应用、数量值、或者按照UTF-8构成字符值串。
表是由多个无符号数或其他表作为数据项构成的复合数据类型,所有表都习惯以“_info"结尾。表用于描述有层次关系的复合结构的数据,整个Class文件本质上就是一张表。如图所示:
2、class文件组成
每个Class文件的头4个字节称为魔数,它的唯一作用是用于确定这个文件是否为一个能被虚拟机接受的Class 文件。值为:0xCAFEBABE。
紧接着魔数的四个字节存储的是Class文件的版本号:第五第六字节是此版本号,第七第八字节是主版本号。
紧接着主次版本号之后的是常量池的入口,这个是Class文件中与其他项目关联最多的数据结构,也是占用文件空间文件最大的数据项目之一,同时也是Class文件中第一个出现的表结构的数据类型。
常量池之中主要存储两大类常量:字面量和符号引用。字面量是语言层的常量的概念,如被声明为final的常量值等。而引用符号常包含下面三类常量:
*类和接口的权限定名
*字段的名称和描述符
*方法的名称和描述符
Java代码在Javac的时候进行动态的链接,也就是说,在Class文件中不会保存各个方法和字段的最终的内存布局信息,因此这些信息需要转换后才能被使用。当虚拟机运行的时候,需要从常量池获得对应的引用,在类创建或者运行的时候解析并翻译到具体的内存当中去。
在常量池结束之后是两个字节的访问标志,用于标识一些类或接口的访问信息,包括:这个Class是类还是接口,定义的类型等。
接下来是类索引、父类索引、接口索引,都是u2类型,作用如字面所示。接下来还有:
*字段表集合:用于描述接口或类中声明的变量。包含的信息有:字段的作用域,是类级别还是实例级别,并发可见行,能否序列化,字段数据类型、字段名称等。
*方法表集合:包含访问标志,名称索引、描述索引、属性表集合等。
*属性表集合:字段表、方法表中都可以携带自己的属性表集合,用来描述某些场景专用的信息。
3、小结
Class 文件是Java虚拟机执行引擎的数据入口,这里只进行了简单的说明,如果想进行深入的了解,请查看《深入理解JAVA虚拟机》