天天看點

【Java 虛拟機原理】Class 位元組碼二進制檔案分析 五 ( 方法計數器 | 方法表 | 通路标志 | 方法名稱索引 | 方法傳回值類型 | 方法屬性數量 | 方法屬性表 )

文章目錄

  • 前言
  • 一、方法表結構
  • 二、方法計數器
  • 三、方法表資料解析 ( init 構造方法 )
    • 1、方法通路标志
    • 2、方法名稱索引
    • 3、方法傳回類型
    • 4、方法屬性數量

前言

上一篇部落格 【Java 虛拟機原理】Class 位元組碼二進制檔案分析 四 ( 字段表資料結構 | 字段表詳細分析 | 通路标志 | 字段名稱 | 字段描述符 | 屬性項目 ) 分析了字段表的一些資料 ;

目前的位元組碼檔案中隻有

1

1

1 個字段 , 字段表顯示

1

1

1 個字段結束後 , 後面的位元組是 方法計數器 和 方法表 的資料 ;

【Java 虛拟機原理】Class 位元組碼二進制檔案分析 五 ( 方法計數器 | 方法表 | 通路标志 | 方法名稱索引 | 方法傳回值類型 | 方法屬性數量 | 方法屬性表 )

本篇部落格中 , 繼續向後分析 位元組碼對應資料 ;

分析的原始資料是 【Java 虛拟機原理】Class 位元組碼二進制檔案分析 一 ( 位元組碼檔案附加資訊 | 魔數 | 次版本号 | 主版本号 | 常量池個數 ) 二、位元組碼檔案示例 章節中的 Java 源碼 , Class 位元組碼 , 位元組碼附加資訊 ;

public class Student {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
           

位元組碼附加資訊 :

D:\jvm>javap -v Student.class
Classfile /D:/jvm/Student.class
  Last modified 2021-9-4; size 392 bytes
  MD5 checksum 8b9bb897bb8cf2a8addf04be5b7b915f
  Compiled from "Student.java"
public class Student
  minor version: 0
  major version: 52
  flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
   #1 = Methodref          #4.#17         // java/lang/Object."<init>":()V
   #2 = Fieldref           #3.#18         // Student.name:Ljava/lang/String;
   #3 = Class              #19            // Student
   #4 = Class              #20            // java/lang/Object
   #5 = Utf8               name
   #6 = Utf8               Ljava/lang/String;
   #7 = Utf8               <init>
   #8 = Utf8               ()V
   #9 = Utf8               Code
  #10 = Utf8               LineNumberTable
  #11 = Utf8               getName
  #12 = Utf8               ()Ljava/lang/String;
  #13 = Utf8               setName
  #14 = Utf8               (Ljava/lang/String;)V
  #15 = Utf8               SourceFile
  #16 = Utf8               Student.java
  #17 = NameAndType        #7:#8          // "<init>":()V
  #18 = NameAndType        #5:#6          // name:Ljava/lang/String;
  #19 = Utf8               Student
  #20 = Utf8               java/lang/Object
{
  public Student();
    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 1: 0

  public java.lang.String getName();
    descriptor: ()Ljava/lang/String;
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: getfield      #2                  // Field name:Ljava/lang/String;
         4: areturn
      LineNumberTable:
        line 5: 0

  public void setName(java.lang.String);
    descriptor: (Ljava/lang/String;)V
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=2, args_size=2
         0: aload_0
         1: aload_1
         2: putfield      #2                  // Field name:Ljava/lang/String;
         5: return
      LineNumberTable:
        line 9: 0
        line 10: 5
}
SourceFile: "Student.java"
           

一、方法表結構

字段表之後的

2

2

2 位元組就是方法計數器 , 記錄目前位元組碼有多少個方法 ;

方法計數器 後 就是方法表 , 方發表中每個方法都是 一個 method_info 資料結構 ;

假如 方法計數器 中 方法個數是

3

3

3 , 那麼方法表中有

3

3

3 個 method_info ;

【Java 虛拟機原理】Class 位元組碼二進制檔案分析 五 ( 方法計數器 | 方法表 | 通路标志 | 方法名稱索引 | 方法傳回值類型 | 方法屬性數量 | 方法屬性表 )

方法表 method_info 結構 : 方發表結構 與 字段表結構一樣 ;

【Java 虛拟機原理】Class 位元組碼二進制檔案分析 五 ( 方法計數器 | 方法表 | 通路标志 | 方法名稱索引 | 方法傳回值類型 | 方法屬性數量 | 方法屬性表 )

方發表就是若幹上述 method_info 結構的排列 , 方法表的方法排列完畢後 , 是屬性計數器 和 屬性表 ;

二、方法計數器

方法計數器的值為

00 03

, 說明有

3

3

3 個方法 ;

【Java 虛拟機原理】Class 位元組碼二進制檔案分析 五 ( 方法計數器 | 方法表 | 通路标志 | 方法名稱索引 | 方法傳回值類型 | 方法屬性數量 | 方法屬性表 )

三、方法表資料解析 ( init 構造方法 )

這是位元組碼 附加資訊 中的構造方法資料 :

public Student();
    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 1: 0
           

1、方法通路标志

access_flag ( 方法通路權限 ) : 方法計數器 後 的

2

2

2 位元組 , 是 方發表中 第一個 method_info 方法資訊的 方法通路标志 ;

00 01

表示該方法是 public 的 ;

【Java 虛拟機原理】Class 位元組碼二進制檔案分析 五 ( 方法計數器 | 方法表 | 通路标志 | 方法名稱索引 | 方法傳回值類型 | 方法屬性數量 | 方法屬性表 )

方法通路标志 :

【Java 虛拟機原理】Class 位元組碼二進制檔案分析 五 ( 方法計數器 | 方法表 | 通路标志 | 方法名稱索引 | 方法傳回值類型 | 方法屬性數量 | 方法屬性表 )

2、方法名稱索引

name_index ( 方法名稱索引 ) :

2

2

2 位元組 ,

00 07

表示常量表中的

#7

, 常量為 :

Constant pool:
   #7 = Utf8               <init>
           

<init>

方法指的是構造方法 ;

【Java 虛拟機原理】Class 位元組碼二進制檔案分析 五 ( 方法計數器 | 方法表 | 通路标志 | 方法名稱索引 | 方法傳回值類型 | 方法屬性數量 | 方法屬性表 )

3、方法傳回類型

descriptor_index ( 方法傳回類型 ) :

2

2

2 位元組 ,

00 08

表示常量表中的

#8

, 常量為 :

Constant pool:
   #8 = Utf8               ()V
           

()V

方法的傳回類型是 void , 沒有傳回類型 ;

【Java 虛拟機原理】Class 位元組碼二進制檔案分析 五 ( 方法計數器 | 方法表 | 通路标志 | 方法名稱索引 | 方法傳回值類型 | 方法屬性數量 | 方法屬性表 )

4、方法屬性數量

attributes_count ( 方法屬性數量 ) :

2

2

2 位元組 ,

00 01

表示方法屬性數量

1

1

1 個