class文件结构

来源:互联网 发布:编译安卓rr源码教程 编辑:程序博客网 时间:2024/06/08 16:30
Class文件的结构:魔数、字段表集合、方法表集合、属性表集合、类索引、父类索引、接口索引集合、访问标志、常量池
可以分为无符号数和表:两者当遇到数量不定的多个数据时,会使用一个前置的容量计数器加若干个连续的数据项的形式,这时称为某一类型或某一类型数据的集合。(这个计数器是除了常量池从1开始,其他的都是从0开始的)
1,魔数:每个Class文件的头四个字节称为魔术他的唯一作用是确定这个文件是否为一个能被虚拟机接受的Class文件,(gif、jpeg等很多文件头中都存有魔数)为了安全,毕竟扩展名是可以改的。
高版本的JDK能向下兼容以前版本的Class文件,但也拒绝执行超过其版本号的Class文件,
2,紧接着后面的四个字节存储得是Class文件的版本号,第五六个字节是次版本号,第七个和第八个字节是主版本号,下图可以对应的查出该Class文件可以被执行的JDK的版本。

3,常量池
紧接着版本号是常量池
常量池的集合是从1开始的,把0空出来是为了满足后面某些指向常量池的索引值的数据在特定情况下需要表达“不引用任何一个常量池项目”这样他就可以把索引值置为0来表示。
常量池中主要存放着两大类常量:字面量和符号引用,字面量比较接近Java语言层面的常量,如文本字符串、声明为final的常量值,
符号引用则属于编译原理方面的概念:包括以下三类常量
a,类和接口的全限定名
b,字段的名称和描述符
c,方法的名称和描述符

4,访问标志(有16个标志位可用没有用到的全置为0)
类变量结束后,紧接着的两个字节代表访问标志,这个标志用于识别一些类或者接口层次的访问信息,如:这个Class是类还是接口、是否定义为public类型、是否定义为abstract类型等可以参考下表

5,类索引、父类索引与接口索引集合
类索引、父类索引都是一个u2型数据,接口索引是一个u2数据的集合,除了Object类所有的类的父索引都不为零,
6,字段表集合
用于描述接口或者类中声明的变量,包括类级变量以及实例级变量,但不包括在方法内部声明的局部变量。一个字段可以包含的信息:字段的作用域、是实例变量还是类级变量,是否可变(即是否被final修饰)并发可见性(volatile修饰符,是否强制从主内存读写)、可被序列化(transient修饰符)、字段数据类型(基本类型、对象、数组)、字段名称
全限定名和简单名称:全限定名是吧类的全名称(带有包名的)中的“.”换为了“/”一般会在结束后加一个;分号,简单名称是指没有类型和参数修饰的方法和字段名称,如方法equals、字段age等
相对于全限定名和简单名称来说,方法和字段的描述符就要复杂一些,描述符的作用就是被用来描述字段的数据类型、方法的参数列表(包括数量、类型、以及顺序)和返回值,

不会列出父类或超类继承来的字段,但会多一些原本不存在的字段如:内部类为了保证对外部类的访问,会自动添加指向外部类实例的字段。
7,方法表集合
访问标志、名称索引、描述符索引、属性表集合等,方法体(也就是方法里的代码)经过编译器编译成字节码指令后,存放在方法属性表集合里的一个Code字段里,
与字段表相对应的是,如果父类方法在子类中没有被重写方法表集合中就不会出现父类的方法信息,当然也可能存在编译器自动添加的方法,最典型的就是类的空参构造器和初始化方法。
8,属性表集合
前面已经多次提到了属性表
方法体中定义的局部变量需要使用局部变量表来存放
参考:深入理解Java虚拟机 JVM高级特性与最佳实践(第六章)




原创粉丝点击