语言无关性
各种语言由源代码编译成 Class 文件,最终得以在 Java 虚拟机上执行;
Class 文件
Class 文件的结构严格定义为:
- 文件以一个 4 字节的 Magic (魔数)开头,紧跟着两个大小版本号;
- 版本号之后是常量池;
- 之后是类的访问修饰符、代表自身类的引用、父类引用以及接口数量和实现的接口引用;
- 接口之后,有着字段的数量和字段描述、方法数量以及方法的描述;
- 最后,存放着类文件的属性信息;
Class 文件标志 —— 魔数
魔数(Magic Number)作为 Class 文件的标志,用来告诉 Java 虚拟机,这是一个 Class 文件。魔数是一个 4 个字节的无符号整数,固定为 0xCAFEBABE。
/** * @author caojiantao */public class SimpleUser { public static final int TYPE = 1; private int id; private String name; public int getId(){ return id; } public void setId(int id) throws IllegalMonitorStateException { try { this.id = id; } catch (IllegalStateException e) { System.out.println(e.toString()); } } public String getName() { return name; } public void setName(String name) { this.name = name; }}复制代码
编译生成 Class 文件,通过 Sublime Text 打开:
Class 文件的版本
紧接着是 Class 的小版本和大版本号,表示当前 Class 文件,由哪个版本的编译器编译产生的。
版本号和 Java 编译器的对应关系如下表所示:
小版本 | 大版本 | 编译器版本 |
---|---|---|
3 | 45 | 1.1 |
0 | 46 | 1.2 |
0 | 47 | 1.3 |
0 | 48 | 1.4 |
0 | 49 | 1.5 |
0 | 50 | 1.6 |
0 | 51 | 1.7 |
0 | 52 | 1.8 |
对应上图大版本号为 0x34,换算为 10 进制为 52,因此判断该 Class 文件有 JDK 1.8 编译器生成的。
... ...
操作字节码:走进 ASM
ASM 是一款 Java 字节码的操作库,像 AspectJ、Spring 以及 CGLIB 都是 ASM 的使用者。由于它直接工作与底层,性能很高,使用也较为灵活。