一 Class类的文件结构
解析Class文件的数据结构是本次最重要的内容
任何一个class文件都对应着为一个类或者接口的定义信息,反过来说,类和接口并不一定都得定义在文件里(譬如类或者接口也可以通过类加载器直接生成)
Class文件是一组以8位字节为基础单位的二进制流,各个数据项目严格按照顺序紧凑的排列在class文件之中,中间没有任何分隔符,全都是必要数据,没有空隙存在
一 魔数与Class文件的版本
1.魔数:每个Class文件的头4个字节称为魔数
2.作用:它唯一的作用是确定这个文件是否为一个能被虚拟机接受的Class文件。很多文件存储标准都使用魔数来进行身份识别,譬如图片格式
3.Class文件版本号:紧接着魔数的4个字节存储,第5和第6个字节是次版本号(Minor version),第7和第8是主版本号(Major version)
二 常量池
1.常量池:主次版本号之后就是常量池入口,常量池可以理解为Class文件之中的资源仓库,他是Class文件结构中与其他项目关联最多的数据类型,也是占用Class空间最大的数据项目之一,同时他哈市Class文件中第一个出现表类型数据项目
2.常量池计数值(constant_pool_count):常量池中常量的数量是不固定的,所以常量池入口需要放置一项U2 类型的数据,容量计数从1开始的而不是0
3.常量池的两大类常量:字面量(Literal)和符号引用(Symbolic References)
4.字面量比较接近于Java语言层面的常量概念,如文本字符串,声明为final的常量值等
5.符号引用则属于编译原理方面的概念,包括了下面的三类常量
类和接口的全限定名(Fully Qualified Name)
字段名称和描述符(Descriptor)
方法的名称和描述符
6.14种常量类型所代表的具体含义
14种常量项的结构总表
三 访问标志
1.访问标志:常量池后两个字节代表访问标志(access_flags)
2.作用:用于识别一些类或者接口层次的访问信息,包括,这个Class是类还是接口,是否定义public,是否定义abstract,如果是类的话是否被声明final等
四 类索引,父类索引和接口索引集合
1.类索引和父类索引都是一个U2类型的数据,而接口索引集合是一组U2类型的数据的集合
2. 作用:Class文件中由这三项数据确定这个类的继承关系,类索引确定这个类的全限定名,父类索引用于确定这个类的父类的全限定名,由于java语言不允许多继承,所以父类索引只有一个,除了java.lang.Object之外,所有的类都有父类,因此除了java.lang.Object外,所有java类的父类索引都不为0,接口索引集合就用来描述这个类实现了那些接口,这些被实现的接口将按implements语句(如果这个类本身就是一个接口,则应当是extends语句)后的接口访问顺序从左到右排列在接口索引集合中
五 字段表集合
1.字段表是用于描述接口或者类中声明的变量
2.字段包括类级变量以及实例级变量但是不包括方法内部声明的局部变量
3.描述一个字段包含的信息有:字段的作用域(public private protected修饰符),是实例变量还是类变量(static修饰符),可变性(final),并发可见性(volatile修饰符,是否强制从主内存读写),可否被序列化(transient修饰符),字段数据类型(基本数据类型,对象,数组),字段名称,在上述信息中,各个修饰符都是布尔值,要么有,要么没有
六方法表集合
1.方发表的结构:访问标志(assecc_flags),名称索引(name_index),描述符索引(descriptor_index),属性表集合(attributes)
七 属性表集合