一、Class文件的结构
学过java都知道,java是跨平台的,“一次编译,到处运行”是java诞生之时就有的口号。原因就在于“字节码”。
各个不同平台的虚拟机和所有平台都统一的使用字节码这种格式存储,就是构成平台无关性的基石。另外要说的一点是Class文件并不是说只有java程序会生成,也就是说java虚拟机并不是指只有java语言才能运行。只要是在经过编译后生成符号虚拟机规范的Class文件,都可以在java虚拟机中运行!如果JRuby,Groovy等(反正我也没用过)。
至于什么是符合虚拟机规范的Class文件,就是我们接下来要说的了:
Class文件是一组以8位字节为基础的二进制流,各个数据项目严格按照顺序紧凑排列在Class文件中,中间没有任何分隔符,整个Class文件中存储的内容几乎全部是程序运行的必要数据,没有空隙存在。如果遇到要占用8位字节以上空间的数据项,会按照高位在前的方式分割若干个8位字节进行存储。以u1,u2,u3,u4,u8来分别 代表1,2,3,4,8个字节的无符号数,无符号数可以描述数字,索引引用,数量值或者按照UTF-8编码构成字符串值。
然后整个class文件就可以用一张表来描述其构成:
图中,以_info结尾的表示符合数据类型,里面有较多数据的表。
我们写一个简单程序:
public class MyTest01 {
public static void main(String[] args) {
int a = 1;
System.out.println(a);
}
}
获取到其class文件后,用16进制编辑器打开:
内容还是相当丰富的,就从头分析一下吧!
1.1、魔数:每个Class文件的头4个字节称之为魔数
作用很简单,就是看你这个Class文件是不是能被虚拟机认可。作用类似于文件扩展名,但是这个是Class文件内部,所以无法修改的。Class文件中的魔数是固定的,值为0xCAFEBABE。也就是下图中第一块。
1.2、版本号:魔数后4个字节为Class文件的版本号
第五六个字节是次版本号,第七八个字节是版本号。版本号是从45开始,图中主版本号16进制为34,对应的十进制为52。也就是jdk 1.8。
下面是常量池,常量池内容较多,我放在下一篇中单独来说
另外:我用的是Hex Editor进行的编辑,下载地址