什么是class文件
恩,开始写。
众所周知,JAVA源文件会被编译成class文件,虚拟机运行的也是class文件。JVM从发布之初就一直贯彻的两个特性,其一,平台无关性,其二,语言无关性。
并不是只有java代码才可以被编译成class文件,仅仅只是虚拟机运行的是class文件,这不是因果关系。换言之,只要可以编译成class文件,任意语言都可以在虚拟机上运行(注意:理论上是这样的)。
class文件是一种结构紧凑,且编码顺序被严格定义的二进制文件,取替了内存上的对齐填充(注一)。以字节为单位编码,且只有两种数据类型(结构):无符号数和表。无符号数分四种类型:u1、u2、u4、u8代表了一字节、两字节、四字节、八字节数据,大于此长度便分成多段以大端方式存储(注二)。
具体结构
魔数:class文件前四字节所表述的含义固定,内容也固定,就是CAFEBABE,恩,可以看做商标。
版本号:魔数之后的四字节是版本号,前两字节为此版本号(u2类型),后两字节为主版本号(u2类型)。
常量池:版本号之后就是class文件中最重要最繁琐的常量池,它是一张表,长度由java源文件决定。前两个字节位是长度,注意这里的长度并不是这张表占多少个字节,而是代表常量池里有多少个常量(每个变量也是一张表),目前总共有十四种常量类型,下表列出:
类型 | 标志 | 描述 |
---|---|---|
CONSTANT_Utf8_info | 1 | UTF8编码的字符串 |
CONSTANT_Integer_info | 3 | 整形字面量 |
CONSTANT_Float_info | 4 | 浮点型字面量 |
CONSTANT_Long_info | 5 | 长整形字面量 |
CONSTANT_Double_info | 6 | 双精度字面量 |
CONSTANT_Class_info | 7 | 类或接口的符号引用 |
CONSTANT_String_info | 8 | 字符串类型字面量 |
CONSTANT_Fieldref_info | 9 | 字段的符号引用 |
CONSTANT_Methodref_info | 10 | 类中方法的符号引用 |
CONSTANT_InterfaceMethodref_info | 11 | 接口中的符号引用 |
CONSTANT_NameAndType_info | 12 | 字段或方法的部分符号引用 |
CONSTANT_MethodHandle_info | 15 | 表示方法句柄 |
CONSTANT_MethodType | 16 | 标识方法类型 |
CONSTANT_InvokeDynamic_info | 18 | 表示一个动态方法调用点 |
内容过多,先不一一介绍了,常量池长度之后的若干个字节就是上述的各种表,每种常量都被编码一张表,每个常量池中常量的类型与个数全部取决于源代码,且上述的每种表都具有严格的定义,标志位在前、读取规则都是固定的。
类信息:常量池之后的是两个字节标志位,标识类的一些属性,例如:公有/私有、final吗、静态吗、抽象吗等等,两个字节总共有十六个标志位,目前只用了其中的八个。
类名(全限定名 包名+类名):占两字节,是指向常量池的引用。
父类名:占两字节,同为指向常量池的引用,Object无父类,为零。
接口表:由长度(u2类型)和指向常量池的接口名引用组成,引用的顺序由implements(extends)关键字之后的接口顺序决定。
字段表:记录类字段信息(实例变量和静态变量,注意与局部变量区分,局部变量在局部变量表里,局部变量表可能在栈里),每个字段都是一张表,用以说明这个字段的所有信息,当然结构也是固定的。
方法表:和字段表类似,记录方法签名信息的,结构固定,值得一提的是,看上去方法体和方法签名是分开存储的。
属性表:class文件中唯一可拓展内容的部分,字段表方法表的每个字段也包含一张属性表,方法体就在大方法表内每个具体方法表的属性表的Code表中(这表中有表的结构说着很是绕口),class文件最后的属性表大都用以实现不断加入的一些特性(所以它是可拓展的),比如泛型反射、内部类描述等,很是繁琐。
如果表的长度不固定,那么表的开始字节必定先给出表的长度。
方法体中的代码被翻译成code表中的字节码指令,JVM执行也是这些字节码指令,类似于汇编,机器语言,这里不做介绍。
恩,简单的说明了一下class文件的大概样子,深入了解还需自己对着class文件仔细观察。
注一:对齐填充是一种内存空间上的取整方式,为了方便操作,有些系统和编译器会把申请的内存自动扩充2的整数次幂,比如系统底层的运行栈的每一个栈帧就会被自动扩充容量(如果它的大小不满足2的整数次幂的话)。
注二:大端方式是存储数据的一种方式,高位在前低位在后,二进制数的高低位与平时相反,即从左至右视为从高到低。