一、概述
方法表集合与属性表集合的结构类似,是对方法的修饰符、返回类型、方法名、参数个数、参数类型、方法体的描述集合。
方法表集合的结构是一个类似于数组的结构,JVM在对java文件进行编译时,会将类中的方法个数放到方法计数器中,然后将每个方法组成method_info结构,依次存在在方法计数器之后。
二、方法表集合的构成
方法表集合的结构与字段表结构非常的类似,开头也是用了两个字节表示方法的个数,然后接着是每个方法的描述。
1.方法计数器
方法表集合是由很多method_info组成的,所以方法表集合的前两个字节表示有多少个方法,占两个字节,16位。
2.method_info
method_info{
access_flag;//访问修饰符
name_index;//方法名称(这里是常量池中的index)
descriptor_index;//参数的类型以及返回值得类型(同样指向常量池得编号)
attributes_count;//属性个数
attibutes;//属性表(这里得属性个数及属性表都放在属性表中得‘Code’属性里面)
}
3.access_flags
与属性表集合的相同,这里不再重复,请参考《JVM虚拟机-Class文件之字段表集合》相关部分内容。
4.name_index和descriptor_index
name_index和descriptor_index,是对常量池的引用,name_index指字段的简单名称,descriptor_index指字段描述符。
descriptor_index描述符用来描述方法的参数列表(包括数量,类型以及顺序)和返回值.根据描述符规则,无返回值的void类型都用一个大写字符来表示。
三、实例拆解
定义一个类:
public class HelloWord{
public Object test(){return null;}
}
字节码文件:
public class com.csdn.reader.HelloWord
minor version: 0
major version: 52
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 = Methodref #3.#15 // java/lang/Object."<init>":()V
#2 = Class #16 // com/csdn/reader/HelloWord
#3 = Class #17 // java/lang/Object
#4 = Utf8 <init>
#5 = Utf8 ()V
#6 = Utf8 Code
#7 = Utf8 LineNumberTable
#8 = Utf8 LocalVariableTable
#9 = Utf8 this
#10 = Utf8 Lcom/csdn/reader/HelloWord;
#11 = Utf8 test
#12 = Utf8 ()Ljava/lang/Object;
#13 = Utf8 SourceFile
#14 = Utf8 HelloWord.java
#15 = NameAndType #4:#5 // "<init>":()V
#16 = Utf8 com/csdn/reader/HelloWord
#17 = Utf8 java/lang/Object
{
public com.csdn.reader.HelloWord();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
LineNumberTable:
line 3: 0
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this Lcom/csdn/reader/HelloWord;
public java.lang.Object test();
descriptor: ()Ljava/lang/Object;
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aconst_null
1: areturn
LineNumberTable:
line 4: 0
LocalVariableTable:
Start Length Slot Name Signature
0 2 0 this Lcom/csdn/reader/HelloWord;
}
SourceFile: "HelloWord.java"
方法解析:
四、总结
方法表集合中不会列出从父类或者父接口中继承而来的方法,但有可能列出原来Java代码中不存在的方法,比如无参构造方法。
参考资料: