1.引言
- 以前编写程序都是编译成二进制本地机器码,然而现在选择了新的文件格式----------Class文件。
- 以前总以为程序的“一次编写,到处运行”指的是java程序,现在才发现指的是所有可以编译存储为Class文件的编程语言,虚拟机可以载入和执行同一种(平台无关)的字节码。
- 以前只知道java的跨平台是虚拟机实现的,现在底层实际是虚拟机先将程序编译成Class文件,然后在不同的平台(所谓的平台指的是不同的操作系统,不同的CPU有不一样的机器指令集)上转换成机器码。
2 Class类文件结构
Class文件以8位字节为基础的二进制流,包含无符号数和表两种数据结构。
无符号数属于基本的数据结构,以u1,u2,u4,u8分别代表1个字节,2个字节,4个字节和8个字节的无符号数,无符号数可以用来描述数字,索引引用,数量值或者按照UTF-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 | interface_count | 1 |
u2 | interface | interface_count |
u2 | fields_count | 1 |
field_info | fields | fields_count |
u2 | methods_count | 1 |
method_info | methods | methods_count |
u2 | attribute_count | 1 |
attribute_info | attribute | attributes_count |
我们用简单的java代码待观察Class文件格式。
public class ClassForm {
private int m;
public static void main(String[] args) {
}
public int test() {
return m+1;
}
}
然后用WinHex打开这个Class文件:
2.1魔数
· 每个Class文件的头四个字节是魔数(Magic Number),它的唯一作用是确定这个文件是否为一个能被虚拟机接受的Class文件。魔数值为:CAFEBABE。