目录
前面日志说到,Java程序中的类编译后会生成对应的.class字节码文件,里面的数据都是二进制流存储,一个字节码文件由很多部分组成,例如魔数,版本号,常量池,访问权限和接口列表等等,这些数据项对应的字节流都是按照顺序存储的,例如.class文件开头的四个字节一定是魔数,它用来标识该文件是字节码文件,JVM在加载.class文件时都会先检查前面这四个字节,如果发现不是固定的魔数,那么会拒绝加载。平时想要查看字节码内容,可以用javap -verbose命令,它可以分析出字节码文件中例如版本号,常量池和类的构造函数等信息:

可以看到,版本号53,对应的即使用JDK 9编译,常量池,里面保存了很多索引。下面用十六进制打开一个Java程序的编译后得到的字节码文件,来详细分析一下里面的每一部分。
十六进制字节码
字节码用二进制数据流的方式存储,想用十六进制方式打开,我使用的是WinHex,打开编译后的.class文件:

魔数
首先来看前面四个字节的数据,CAFEBABE,正是我们前面所说的,标识.class字节码文件的魔数:

魔数除了在JVM中有体现外,在其他地方,例如可执行文件ELF文件中也会用到魔数,它会检查这个magic number和预期的是否一样,如果不同,则表明该文件已损坏。还有在缓冲数组中放一个魔数来检测缓冲区溢出等。

本文详细介绍了.class字节码文件的结构,重点分析了魔数、版本号和常量池的内容。通过魔数确认文件性质,版本号揭示编译使用的JDK版本。常量池作为关键组成部分,包含了类、方法、变量等各种信息的引用。通过字节码分析,可以了解Java类的内部构造和执行机制。
最低0.47元/天 解锁文章
8206

被折叠的 条评论
为什么被折叠?



