class文件结构

前面讨论JVM内存模型和JVM运行原理时,我们多次提及到了class文件,当时为了行为内容的简洁,并没有展开描述,今天我们就来认识一下这个文件。

我们知道,JVM在执行某个类的时候,必须经过加载、连接、初始化,而连接又包括验证、准备、解析三个阶段。

在加载类的时候,JVM会先加载class文件,而在class文件有类的版本、字段、方法和常量池(Constant Pool Table)等信息。通过javap反编译一个class文件,就能查看到class文件的内容,其结构如下:

image-20220428175158549

在这里,我们要知道的是,前期编译的过程其实是非常复杂的,包括词法分析、符号表填充、注解处理,语义分析以及生成class文件,但这个过程我们并不用过多关注。只要知道,编译后的字节码文件主要包括常量池和方法表集合就够了。

  • 常量池,用于存放编译期间生成的各种字面量和符号引用。字面量包括字符串常量(例如 String str=“abc”,其中“abc”就是常量)、声明为final的属性以及一些基本类型(例如,范围在-127 ~ 128之间的整型)的属性。符号引用则包括类和接口的全限定名、类引用、方法引用以及成员变量引用(例如 String str=“abc”,其中str就是成员变量引用)等。

  • 方法表集合中主要包含方法字节码、方法访问权限(public、protect、private等)、方法名索引(与常量池中的方法引用对应)、描述符索引、JVM执行指令以及属性集合等。

当类加载到内存后,JVM就会将class文件常量池中的内容放到运行时常量池中;在解析阶段,JVM会把符号引用替换为直接引用(对象的索引值)。

例如,类中的一个字符串常量在class文件中时,存放在class文件的常用池中,而在JVM加载完类之后,这个字符串常量就被放到了运行时常量池中,并在解析阶段,指定该字符串对象的索引值。

注:运行时常量池是全局共享的,多个类共用一个运行时常量池,class文件常量池中多个相同的字符串在运行时常量池只会存在一份。


class文件结构
https://kuberxy.github.io/2020/09/26/了解class文件/
作者
Mr.x
发布于
2020年9月26日
许可协议