目录
前面日志说到,Java程序中的类编译后会生成对应的.class字节码文件,里面的数据都是二进制流存储,一个字节码文件由很多部分组成,例如魔数,版本号,常量池,访问权限和接口列表等等,这些数据项对应的字节流都是按照顺序存储的,例如.class文件开头的四个字节一定是魔数,它用来标识该文件是字节码文件,JVM在加载.class文件时都会先检查前面这四个字节,如果发现不是固定的魔数,那么会拒绝加载。平时想要查看字节码内容,可以用javap -verbose命令,它可以分析出字节码文件中例如版本号,常量池和类的构造函数等信息:
可以看到,版本号53,对应的即使用JDK 9编译,常量池,里面保存了很多索引。下面用十六进制打开一个Java程序的编译后得到的字节码文件,来详细分析一下里面的每一部分。
十六进制字节码
字节码用二进制数据流的方式存储,想用十六进制方式打开,我使用的是WinHex,打开编译后的.class文件:
魔数
首先来看前面四个字节的数据,CAFEBABE,正是我们前面所说的,标识.class字节码文件的魔数:
魔数除了在JVM中有体现外,在其他地方,例如可执行文件ELF文件中也会用到魔数,它会检查这个magic number和预