大家都知道,JAVA文件通过javac的命令编译生成类文件,类文件再通过java的命令就能运行出我们写的代码了,今天就来研究一下类文件。
class文件的c定义的结构体
struct ClassFile
{
u4 magic; //识别Class文件格式,具体值为0xCAFEBABE,
u2 minor_version; // Class文件格式副版本号,
u2 major_version; // Class文件格式主版本号,
u2 constant_pool_count; // 常数表项个数,
cp_info **constant_pool;// 常数表,又称变长符号表,
u2 access_flags; //Class的声明中使用的修饰符掩码,
u2 this_class; //常数表索引,索引内保存类名或接口名,
u2 super_class; //常数表索引,索引内保存父类名,
u2 interfaces_count; //超接口个数,
u2 *interfaces; //常数表索引,各超接口名称,
u2 fields_count; //类的域个数,
field_info **fields; //域数据,包括属性名称索引,
//域修饰符掩码等,
u2 methods_count; //方法个数,
method_info **methods;//方法数据,包括方法名称索引,方法修饰符掩码等,
u2 attributes_count; //类附加属性个数,
attribute_info **attributes; //类附加属性数据,包括源文件名等。
};
其中u2为unsigned short,u4为unsigned long:
typedef unsigned char u1;
typedef unsigned short u2;
typedef unsigned long u4;
这就是我一开始学时写的Java的的Hello,World。当时写出来看到输出真是开心至极。但是今天的重点放在类文件夹上,其实类文件就是一堆二进制数字。我们使用二进制软件打开,我这边选择的时010 Editor。官网地址http://www.sweetscape.com/010editor/。
上图就是打开编译后的类的十六进制数据,先来说一下魔数和版本号。大家都知道一个十六进制数占4位,两个十六进制数占8位,也就是1个字节,那么前面四个字节表示的就是魔数,这是java的定义的规范,又来校验是否为类文件,当然还有其他的校验方式,这边就不多说了,然后再后面四个字节是版本号。
见上图所示,至于魔数就是固定的这种形式,版本号的对应关系如下:
JDK 1.8 = 52
JDK 1.7 = 51
JDK 1.6 = 50
JDK 1.5 = 49
JDK 1.4 = 48
JDK 1.3 = 47
JDK 1.2 = 46
JDK 1.1 = 45
我们把00 00 代表次版本号 00 34代表主版本号 各占两个字节 主版本号转换为10进制,正好是52,我用的是1.8的JDK,所以对应上了,自己也可以试试看。
明天再继续介绍类的格式。