Java语言中的各种变量、关键字和运算符号的语义最终都是由多条字节码命令组合而成的,因此字节码命令所能提供语义描述能力肯定会比Java语言本身更加强大。因此,有一些Java语言本身无法有效支持的语言特性不代表字节码本身无法有效支持,这也为其他语言实现一些有别于Java的语言特性提供了基础。
Class:在运行java代码时,会将java文件编译成class文件,然后将class文件装载到java虚拟机中。
Class文件是一组以8位字节为基础单位的二进制流,各个数据项目严格按照顺序紧凑地
排列在Class文件之中,中间没有添加任何分隔符,这使得整个Class文件中存储的内容几乎全部是程序运行的必要数据,没有空隙存在。当遇到需要占用8位字节以上空间的数据项时,则会按照高位在前的方式分割成若干个8位字节进行存储。
1.案例
public class TestConstant {
private final int a = 10;
private final int b = 10;
private int c = 11;
private int d = 11;
private long e = -11111110005514L;
private long f = -11111110005514L;
private double g = 10.4557848D;
private double h = 10.4557848D;
private String y = "JVM";
private String j = "JVM";
}
编译成class文件,使用UltraEdit打开,可以得到Java编译后的字节码
2.Class文件的结构
Class文件格式采用一种类似于C语言结构体的伪结构来存储数据,包含量中两种数据类型。
- 无符号数
类型有u1、u2、u4、u8分别代表1个字节、2个字节、4个字节、8个字节。
- 表
表是多个无符号数或者其他表组合而成的复合数据,例如:fields [fields_count]
每个Class文件对应于一个如下的ClassFile结构体
2.魔数和版本号
- 魔数(Magic Number)
魔数是用来标识这个文件是能被虚拟机所接受的Class文件,魔数值固定为: 0xCAFEBABE。每个Class文件头四个字节是魔数。
- 版本号
Class文件版本由次版本号+主版本号组成(minor_version+major_version)。第5,6个字节是次版本号,第7,8字节是主版本号,通过版本号可以知道对应编译器的版本。以下为JDK版本对应的十六进制版本号。
JDK版本号 |
Class版本号 |
16进制 |
1.1 |
45.0 |
00 00 00 2D |
1.2 |
46.0 |
00 00 00 2E |
1.3 |
47.0 |
00 00 00 2F |
1.4 |
48.0 |
00 00 00 30 |
1.5 |
49.0 |
00 00 00 31 |
1.6 |
50.0 |
00 00 00 32 |
1.7 |
51.0 |
00 00 00 33 |
1.8 |
52.0 |
00 00 00 34 |
解析案例: