中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Class文件結構之如何使用字段表與方法表

發布時間:2021-10-20 16:53:34 來源:億速云 閱讀:348 作者:iii 欄目:web開發

本篇內容主要講解“Class文件結構之如何使用字段表與方法表”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“Class文件結構之如何使用字段表與方法表”吧!

 1、字段表

字段表緊隨在接口表索引之后,字段表包含訪問標記、字段名索引、描述符索引、屬性表,其中屬性表包含屬性計數器與屬性集合

以這段代碼為例:

package com.yang.testField;  public class Main {     private volatile int a = 1;     public static final String b = "abc";  }

16進制數據如下圖所示:

Class文件結構之如何使用字段表與方法表

可以看得出,字段計數為0x0002,因為有2個字段,a和b。

字段a的訪問標記是是0x0042,用這個值與標識符的特征值取與,如果結果為1,則表示該字段擁有相應的標識符。字段標識符如下所示:

Class文件結構之如何使用字段表與方法表

這里我們可以得出,a的訪問標記有ACC_PRIVATE與ACC_VOLATILE。

a的名稱索引為0x0005,我們看一下常量池:

Class文件結構之如何使用字段表與方法表

可以得出第一個字段的名稱索引指向常量池中第5個常量項,即“a”。

a的描述符索引為0x0006,即常量池中的“I”,完成的字段類型與描述符的對照表如下:

Class文件結構之如何使用字段表與方法表

接下來是a的屬性計數器,對應的值為0x0000,代表a沒有屬性表。

貼一下b字段表中的屬性表:

Class文件結構之如何使用字段表與方法表

b的屬性計數器為0x0001,代表著有屬性表,屬性表中只有一個元素,為0x0009,常量池中顯示為ConstantValue,說明

該屬性是ConstantValue類型的,屬性長度為2,屬性值索引為0x000A,即找到常量池中的#11,再找到#21,原來是個字符串"abc"。

為什么int a沒有屬性表,而static final b卻有屬性表?這要從字段的賦值策略說起:

對于一個實例字段,比如這里的a,賦值階段發生在對象實例的構造方法中,即;

對于一個非final的靜態字段,賦初始值會發生在解析階段,而賦用戶指定的值,會發生在初始化階段,在類構造器方法中完成,即

對于一個final的靜態字段,且是基本類型或者是String類型,在編譯期間就給該變量賦予用戶指定的值,并在常量池中形成一個ConstantValue類型的屬性,屬性值就是常量的值。如果是除去String類型以外的引用類型,那么就是在初始化階段完成賦值操作。

下面以一個例子說明:

package com.yang.testField;  public class Main {     private volatile int a = 1;     public static final String b = "abc";     public static String c="def";     public static Thread d=new Thread();  }

方法內的情況:

Class文件結構之如何使用字段表與方法表

這里面完成的是對實例變量的賦值操作。

方法內的情況:

Class文件結構之如何使用字段表與方法表

這里面完成的是對普通靜態變量c與非String的引用類型變量d的賦值操作。

更多關于對方法的理解,可以參考這篇文章java執行順序之深入理解clinit和init

2、方法表

緊接著字段表的是方法表,方法表和字段表類似,方法表包含方法計數、訪問標記、名稱索引、描述符索引、屬性表,其中屬性表也是包含屬性計數與屬性集合。

方法計數、名稱索引這邊就不再說明了。

方法的訪問標記有:

Class文件結構之如何使用字段表與方法表

這里有一個簡單的例子:

package com.yang.testMethod;  public class Main {     public Main() {     }      private int getInt(int k) {         return k;     }      public static Thread getThread(int i, double d, Runnable runnable) {         System.out.println(i * d);         return new Thread(runnable);     }  }

構造方法的描述符為()V

getInt方法的描述符為(I)I

getThread方法的描述符為(IDLjava/lang/Runnable;)Ljava/lang/Thread;

從這里,我們可以看得出,方法描述符的組織方式是這樣子的:(參數列表內字段的描述符)返回值的描述符

接下來討論方法的屬性表,前面說過了,屬性表包含屬性計數與屬性集合,屬性集合又包含屬性名稱索引+屬性長度+屬性值。

屬性表內最主要的屬性就是Code屬性了,Code屬性內有幾個比較重要的東西:字節碼、LineNumberTable行號表、LocalVariableTable局部變量表、ExceptionTable異常表

用一下的代碼為例:

public static Thread getThread(int i, double d, Runnable runnable) {     try {         System.out.println(i * d);     }catch (Exception e){         return null;     }     return new Thread(runnable); }

字節碼是class文件中最重要的東西了,jvm主要就是抽取字節碼,然后去執行。

Class文件結構之如何使用字段表與方法表

LineNumberTable內維護著java源碼與字節碼之間的對應關系:

Class文件結構之如何使用字段表與方法表

LocalVariableTable內記錄著局部變量描述:

Class文件結構之如何使用字段表與方法表

關于局部變量表的詳細內容,可以參考我的另外一篇文章虛擬機棧的五臟六腑 。

ExceptionTable會告訴虛擬機異常的處理邏輯,比如下圖的異常表,說明如果字節碼從第0行到第10行出現了type類型的異常,那么將會跳轉到第13行的字節碼進行處理。

Class文件結構之如何使用字段表與方法表

到此,相信大家對“Class文件結構之如何使用字段表與方法表”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

广平县| 金昌市| 龙口市| 乌鲁木齐市| 昌江| 老河口市| 青河县| 莒南县| 九龙县| 巴彦淖尔市| 芦山县| 房山区| 扎兰屯市| 浠水县| 会东县| 巴林右旗| 固始县| 都江堰市| 九寨沟县| 巴马| 库尔勒市| 舒兰市| 宜兴市| 伊春市| 晋中市| 延寿县| 河北区| 东乡族自治县| 永清县| 华池县| 漳平市| 顺昌县| 宁强县| 宾阳县| 寻乌县| 高雄市| 罗山县| 个旧市| 康平县| 嘉禾县| 黎平县|