¶方法(Method)
每个方法,包括实例初始化方法和类或者接口初始化方法,它们都由method_info结构体来描述。
在一个class文件中不能有两个方法的方法名和方法描述符相同。
以下是方法结构体的格式:
1 | method_info { |
¶access_flags
以下表是方法需要的访问修饰符:
- 一个类的每个方法可能有 ACC_PUBLIC, ACC_PRIVATE和ACC_PROTECTED之中的一个访问修饰符。
- 一个接口的方法可能有在上面的表中除了ACC_PROTECTED, ACC_FINAL, ACC_SYNCHRONIZED和ACC_NATIVE外的一些访问修饰符。
- 在一个版本号小于52.0(jdk8)的class文件中,一个接口的每个方法必须有ACC_PUBLIC和ACC_NATIVE访问修饰符被设置。
- 在一个版本号大等于52.0的class文件中,一个接口的每个方法必须有ACC_PUBLIC和ACC_PRIVATE中的一个访问修饰符被设置。
- 如果一个类或者接口的一个方法有ACC_ABSTRACT访问修饰符,那么 ACC_PRIVATE, ACC_STATIC, ACC_FINAL, ACC_SYNCHRONIZED,ACC_NATIVE或者ACC_STRICT都不能被设置。
- 每个实例初始化方法能够有ACC_PUBLIC,ACC_PRIVATE,ACC_PROTECTED其中一个访问修饰符被设置,并且也能设置 ACC_VARARGS, ACC_STRICT和ACC_SYNTHETIC这三个标志,但是不能设置这个表中的其他标志。
- 类和接口的初始化方法会被java虚拟机调用。它们的access_flags值除了设置的ACC_STRICT标志的值都会被忽略。
- ACC_BRIDGE访问修饰符被用来表示一个由编译器生成的bridge method。
- ACC_VARAGES标志用来表示这个方法在源码级别采用可变数量参数。
- 如果一个方法被声明为有可变数量的参数,则这个方法的ACC_VARAGES值被设置为1,如果是固定参数则设置为0。
- ACC_SYNTHETIC标志表示这个方法由编译器生成并且不会在源码中显示,除非这个方法是在属性表的Synthetic属性中命名的方法之一。
- 在access_flags其他的没有提到的修饰符的所有位不会被分配,它们在class文件中都会被设置为0,并且被java虚拟机忽略。
¶name_index
- name_index的值必须是常量池表中的一个有效索引。这个索引指向的常量池项必须是一个CONSTANT_Utf8_info结构体,这个结构体用来表示特殊的方法名
或 或一个有效的方法名中的一个。
¶descriptor_index
- descriptor_index的值必须是常量池中的一个有效索引。这个索引指向的常量池项必须是一个CONSTANT_Utf8_info结构体,这个结构体用来表示一个有效的方法描述符。
- 如果方法的access_flags中的ACC_VARAGES标志被设置,那这个方法描述符的最后一个参数描述符需要是一个数组类型。
¶attributes_count
- attributes_count的值表示这个方法的附加属性的数量。
¶attributes[attributes_count]
- 属性表的每个值必须是一个attribute_info结构体。
1 | attribute_info { |
- 一个字段可能有与它有关联的一些可选属性。
- 这些属性的规范定义在以下field_info结构体的属性表中表示:
- 查看属性表的详情请点击这里