各种不同平台的Java虚拟机, 以及所有平台都统一支持的程序存储格式——字节码(Byte Code)是构成平台无关性的基石,所以class文件主要用于解决平台无关性的中间文件。如下图所示:
java虚拟机不与包括Java语言在内的任何程序语言绑定, 它只与“Class文件”这种特定的二进制文件格式所关联, Class文件中包含了Java虚拟机指令集、 符号表以及若干其他辅助信息。
每一个class文件都对应着唯一一个类或者接口的定义信息,但是相对地,类或者接口并不一定都必须定义在文件里(比如类或者接口也可以通过类加载器直接生成)
每个class文件都是由字节流组成,各个数据项目严格按照顺序紧凑地排列在文件之中, 中间没有添加任何分隔符,每个字节流含有8个二进制位,所有的16位,32位和64位长度的数据将通过2个,4个和8个连续的8位字节来对其进行表示,多字节数据总是按照big-endian(大端在前:也就是说高位字节存储在低的地址上面,而低位字节存储到高地址上面)的顺序进行存储,在Java JDK中,可以使用java.io.DataInput、java.io.DataOutput等接口和java.io.DataInputStream和java.io.DataOutputStream等类来访问这种格式的数据Class文件结构采用类似C语言的结构体来存储数据的。
Class文件格式采用一种类似于C语言结构体的伪结构来存储数据,主要有两类数据项,无符号数和表,无符号数用来表述数字,索引引用以及字符串等,比如 u1,u2,u4,u8分别代表1个字节,2个字节,4个字节,8个字节的无符号数,而表是任意数量的可变长项组成,是有多个无符号数以及其它的表组成的复合结构,所有表的命名都习惯性地以“_info”结尾,无论是无符号数还是表, 当需要描述同一类型但数量不定的多个数据时, 经常会使用一个前置的容量计数器加若干个连续的数据项的形式, 这时候称这一系列连续的某一类型的数据为某一类型的“集合”。
二、Class类文件的结构 类型 名称 数量u4 magic 1
u2 minor_version 1
u2 major_version 1
u2 constant_pool_count 1
cp_info constant_pool constant_pool_count-1
u2 access_flags 1
u2 this_class 1
u2 super_class 1
u2 interfaces_count 1
u2 interfaces interfaces_count
u2 fields_count 1
field_info fields fields_count
u2 methods_count 1
method_info methods methods_count
u2 attributes_count 1
attribute_info attributes attributes_count
2.1、魔数和java版本号
每个Class文件的头4个字节被称为魔数(Magic Number) , 它的唯一作用是确定这个文件是否为一个能被虚拟机接受的Class文件。Class文件的魔数取得很有“浪漫气息”,
值为0xCAFEBABE(咖啡宝贝? )
紧接着魔数的4个字节存储的是Class文件的版本号: 第5和第6个字节是次版本号(MinorVersion) , 第7和第8个字节是主版本号(Major Version)
这里我们使用一个简单的代码进行分析:
public class TestClass { private int m; public int inc() { return m + 1; } }