1.字段(fields
)表集合
- 用于描述类或者接口中声明的变量。需要注意的是,字段(
field
)只包括类变量和实例变量,不包括方法内部、代码块内部声明的变量。 - 字段叫什么名字、被定义为什么数据类型,需要引用常量池中的常量来描述。
- 被引用的常量池表对应的项,描述了字段的标识符、访问修饰符、是类变量还是实例变量、是否是常量。
注意:
a)
. 字段表集合中不会列出从父类或者实现的接口中继承来的字段。
b)
.Java
中不可能存在两个同名的字段。但是,在字节码中,只要字段的描述符(用于描述数据类型)不一致,那字段重名就是合法的。
字段表集合分为两部分:字段计数器和字段表。
1.1 字段计数器
a)
字段计数器(fileds_count
)。字段计数器占两个字节。表示当前Class
文件fields
表的成员个数(也就是当前Class
总共有多少个成员变量和静态变量)。
1.2 字段表集合
字段表中每一个成员都是一个field_info
结构,用于描述某一个对应的字段。field_info
又有它自己的表结构。如下图中的表格所示,每一个field_info
包含访问标志、字段名索引等5
个部分。
1.2.1 访问标识
用一个标志来描述字段的修饰符,例如public
、static
、final
等。
1.2.2 字段名索引
指向常量池中的某项,用于描述字段的名字(查询常量池中指定项就可以得到)
1.2.3 描述符索引
用于描述字段的数据类型。
1.2.4 属性计数器和属性表集合
一个字段还可能拥有一些属性,用于存储更多的信息。比如初始化值,一些注释信息等。属性的个数存放在属性计数器中,属性内容存在属性表集合中。
例如:对于一个final
修饰的常量,就会有图中蓝色部分所示的属性表集合。
2.方法表集合
- 用于描述类或者接口中的方法。方法表只描述当前类或接口中的方法,对于父类或父接口的方法不会进行描述。
- 字节码文件中,每一个
method_info
都对应着一个类或接口中的方法信息。 Java
方法重载的时候,无法仅仅依靠两个方法的返回值类型不一样来进行重载,也就是说定义两个方法,方法的名字和参数一样,但是方法的返回值类型不一样,是不允许的。但是在Class
文件中,是允许多个方法的方法签名相同,但是要求这些方法的返回值类型不能相同。
方法表集合也分为两个部分:方法计数器和方法表集合。
2.1 方法计数器
用于描述当前Class
文件中方法表的成员个数(也就是描述当前Class
有多少个方法)。占两个字节。
2.2 方法表集合
- 方法表集合中每一个成员都是一个
method_info
结构。用于描述当前类或接口中的某个方法。 method_info
结构可以表示类和接口中的所有方法,包括实例方法、类方法、初始化方法等。- 每一个
method_info
的结构和字段表的field_info
结构是一样的,也包括访问标志、方法名索引等5
个部分。
2.2.1 访问标志
用于描述方法的修饰符。具体的访问标志如下图所示。
2.2.2 方法名索引
指向常量池中的某项。用于描述方法的名字。
2.2.3 描述符索引
指向常量池中的某项。用于描述方法的参数和返回值类型。例如() I
表示的是没有参数,返回值类型为int
的一个方法。
2.2.4 属性计数器和属性表集合
一个方法也可能存在一些属性,用于存储一些而外的信息,例如字节码指令等。
3.属性表集合
- 字段表、方法表都有自己的属性表集合(这一小节讲解的是方法表中的属性集合)。
属性表集合也分为两部分:属性计数器和属性表集合。
3.1 属性计数器
表示当前属性表中成员个数,每一项都是一个attribute_info
结构。
3.2 属性表集合
- 属性表集合有着通用的格式,如下表所示。包括属性名索引、属性长度以及属性表。也就是说只需说明属性名以及占用的长度即可,属性表的内容可以自己去定义。
- 属性表中的内容可以是多种属性类型,例如
Java8
中就有23
种属性类型。如下图所示,这里列出了几种属性类型。
3.2.1 方法属性表中的Code
属性解读
Code
属性就是存放方法体里面的代码。但是,并非所有方法表都有Code
属性。像接口或者抽象方法,他们没有具体的方法体,因此也就不会有Code
属性了。Code
属性的结构如下所示:
3.2.1.1 Code
属性中的LineNumberTable
属性
LineNumberTable
属性位于Code
属性的属性表中。- 用于描述Java源代码行号和字节码行号之间的对应关系。
3.2.1.2 Code
属性中的LocalVariableTable
属性
LocalVariableTable
属性位于Code
属性的属性表中。- 用于确定方法在执行过程中局部变量的信息。
4.SourceFile属性(了解)
- 在方法表集合之后,用于描述
Class
文件所携带的一些辅助信息,例如,该Class
文件的名称等(无须深入了解)。
更多JVM文章请访问我的JVM专栏:
https://blog.csdn.net/u011069294/category_10113093.html