JVM虚拟机-Class文件之方法表集合

一、概述

方法表集合与属性表集合的结构类似,是对方法的修饰符、返回类型、方法名、参数个数、参数类型、方法体的描述集合。

方法表集合的结构是一个类似于数组的结构,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代码中不存在的方法,比如无参构造方法。

参考资料:

  1. https://blog.csdn.net/xiaoqiu_cr/article/details/86742206
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章