JVM知识总结--Class文件的构成(一)

.java文件通过javac编译器编译后会生成对应的.class文件,对java而言程序的执行都是在jvm中进行的,所以class文件的结构必然要知足jvm的标准;.class是格式严谨的二进制文件,没有任何的空白符和分隔符,必须严格按照JVM标准排列;可使用javap -c命令反编译获得更易阅读的字节码文件html

class文件结构总览

  1. 图片第一列表示字段的类型,第二列是该字段的名称;
  2. U二、U4分别表明2个字节、4个字节的无符号数;
  3. _info结尾的表明class文件中的,表也是由若干个无符号数和若干个表构成,用来表示复杂一些的class内容;
  4. 整个class文件就是一个大的表;

magic,minor_version,major_version

顾名思义,这三个字段分别存储着class文件的魔数,class文件的副版本号和主版本号
值得一提的是magic字段的值自Oak时代就被肯定为0XCAFEBABE,这也许就是为何java和javaer都和咖啡有着深厚的不解之缘java

constant_pool_count,constant_pool[]

  1. constant_pool_count:表示接下来的常量池中常量的个数,但其值等于常量的个数+1
  2. constant_pool[]:从名称能够认为常量池是一个近似数组的数据结构,数组中的每一个元素表明一个常量,该数组的下标为1至constant_pool_count-1,总的来说常量池中的常量分为两类--字面量符号引用
    2.1. 字面量:对应java代码中的字符串,声明为final的常量值等;
    2.2. 符号引用:包括类和接口的全限定名,字段的名称和描述符,方法的名称和描述符,jvm执行程序时,会根据这些符号信息进行解析和翻译,在内存中找到对应的入口地址(相似C类语言的链接,但java发生在运行期);
  3. 常量池中的每个常量都是一个表,表的结构如cp_info {u1 tag;u1 info[];}
    3.1. tag:表示常量的类型,JAVA8有14种,JAVA11新增至17种,添加了CONSTANT_Dynamic(17|JAVA11)、CONSTANT_Module(19|JAVA9)、CONSTANT_Package(20|JAVA9)
    3.2. info:tag后的若干个字节,它们详细表述了该常量的内容,下面简要介绍几个我的认为比较典型的常量类型
    3.2.1. CONSTANT_Utf8_info:结构如u1 tag;u2 length;u1 bytes[length];,用来存储全限定类名、方法名、字段名等,length字段使用了u2存储,所以最大只能为65535Byte;
    3.2.2. CONSTANT_NameAndType_info:结构如u1 tag;u2 name_index;u2 descriptor_index;,其中name_index存储的值为一个CONSTANT_Utf8_info常量在常量池中的下标,该CONSTANT_Utf8_info表示了一个field或method的名称,或<init>,descriptor_index存储的值为一个CONSTANT_Utf8_info常量在常量池中的下标,该CONSTANT_Utf8_info表示了一个field或method的描述符信息
    3.2.3. CONSTANT_Fieldref_info:结构如u1 tag;u2 class_index;u2 name_and_type_index;,用来存储类的字段信息,其中class_index存储的值表示一个CONSTANT_Class_info常量在常量池中的下标,该CONSTANT_Class_info存储了此field所在类的类名信息,name_and_type_index存储的值表示一个CONSTANT_NameAndType_info常量在常量池中的下标,该CONSTANT_NameAndType_info表示了此field的name和描述符信息,相似结构的还有CONSTANT_Methodref_info和CONSTANT_InterfaceMethodref_info
    3.2.4. CONSTANT_MethodHandle_info:结构如u1 tag; u1 reference_kind; u2 reference_index;,其中reference_kind目前仅有1-9九个值,分别表明不一样的methodHandle类型,不一样值表明的含义能够参考官方文档,针对不一样值的reference_kind,reference_index将分别指向CONSTANT_Fieldref_info或CONSTANT_Methodref_info或CONSTANT_InterfaceMethodref_info,用来对methodHandle的内容作更为详尽的描述;
    3.2.5. CONSTANT_Dynamic_info和CONSTANT_InvokeDynamic_info:与其余常量不一样,其余常量表明的内容都被静态记录在常量池中,而这两个常量带表的内容由其中所记录的引导方法(bootstrap method)动态生成,前者用来生成field,后者用来生成method,结构如u1 tag; u2 bootstrap_method_attr_index; u2name_and_type_index;,bootstrap_method_attr_index表示所使用的引导方法在class文件中的引导方法表中的下标,CONSTANT_NameAndType_info表示一个CONSTANT_NameAndType_info常量在常量池中的下标,该CONSTANT_NameAndType_info存储着会动态生成的field或method的描述信息

access_flags

用来表示类或接口的访问权限,以及内部元素的标志信息,须要注意的是access_flags被定义为掩码,所以虽然使用的是u2类型,但仅有16个标志位可使用,每一个access_flag仅在一个标志位上为1,其余位所有为0,目前定义了九个,分别用来标识public/final/super/interface/abstract/synthetic/annotation/enum/module,具体解释能够参考官方文档bootstrap

参考

《深刻理解Java虚拟机》数组

Oracle JVMS数据结构

相关文章
相关标签/搜索