結構圖數組
常量池併發
主要存放兩大常量spa
字面量:如文本字符串,被聲明未final的常量值等。.net
符號引用:調試
被模塊導出或開放的包(Package)code
類和接口的全限定名(Fully Qualified Name)對象
字段的名稱和描述符(Descriptor)blog
方法的名稱和描述符繼承
方法句柄和方法類型(Meathod Handle 、Method Type 、Invoke Dynamic)索引
動態調用點和動態常量 (Dynamically-Computed Call Site,Dynamically-Computed Constant)
常量池項目類型
常量池結構表
訪問標誌:用於識別一些類或接口層次的訪問信息,是類仍是接口,是否認義未Public,abstract,final等。共有16個標誌位可用,目前只定義了9個,其餘爲0
類索引、父類索引與接口索引集合
其中類索引和父類索引都是一個u2類型的數據,而接口索引集合是一組u2類型的數據。在Java中因爲不容許多繼承,因此父類索引是惟一的,可是一個類能夠實現多個接口,因此獲得的接口索引是一個集合,表示這個類實現了哪些接口,對於接口索引集合,入口第一項u2爲接口計數器。
字段表集合
描述一個字段的信息包括:字段的做用域(public、protected、private)、實例變量與否(static)、可變性(final)、併發可見性(volatile)、能否被序列化(transient)、字段數據類型(基本數據類型、對象、數組)、字段名稱。字段的信息也被存放在一張表中,其字段表包括三種類型:
u2類型訪問標誌(access_flags),其訪問標誌在access_flags中
u2類型的name_index(字段的簡單名稱)
u2類型的描述符(descriptor_index)
還有u2類型的attributes_count(1個),attributes_count個attribute_info類型的attributes。
方法表集合
結構與字段表同樣,僅訪問標誌(沒有volatile,transient有鎖,native,strictfp,abstract)和屬性表集合的可選項有所區別。
代碼經Javac編譯成字節碼指令後,存放在屬性表集合名爲Code的屬性中
類構造器,實例構造器可能會有編譯器自動添加
重載:要與元方法具備相同的簡單名稱還要有不一樣的特徵簽名
特徵簽名:一個方法中各個參數在常量池中的字段符號引用的集合(因此沒法根據反回值不一樣對方法進行重載)
屬性表集合(詳見https://blog.csdn.net/en_joker/article/details/79868865)
虛擬機中預約義的屬性:
屬性名稱 | 使用位置 | 含義 |
Code | 方法表 | Java代碼編譯成的字節碼指令 |
ConstantValue | 字段表 | final關鍵字定義的常量池 |
Deprecated | 類,方法,字段表 | 被聲明爲deprecated的方法和字段 |
Exceptions | 方法表 | 方法拋出的異常 |
EnclosingMethod | 類文件 | 僅當一個類爲局部類或者匿名類是才能擁有這個屬性,這個屬性用於標識這個類所在的外圍方法 |
InnerClass | 類文件 | 內部類列表 |
LineNumberTable | Code屬性 | Java源碼的行號與字節碼指令的對應關係 |
LocalVariableTable | Code屬性 | 方法的局部便狼描述 |
StackMapTable | Code屬性 | JDK1.6中新增的屬性,供新的類型檢查檢驗器檢查和處理目標方法的局部變量和操做數有所須要的類是否匹配 |
Signature | 類,方法表,字段表 | 用於支持泛型狀況下的方法簽名 |
SourceFile | 類文件 | 記錄源文件名稱 |
SourceDebugExtension | 類文件 | 用於存儲額外的調試信息 |
Synthetic | 類,方法表,字段表 | 標誌方法或字段爲編譯器自動生成的 |
LocalVariableTypeTable | 類 | 使用特徵簽名代替描述符,是爲了引入泛型語法以後能描述泛型參數化類型而添加 |
RuntimeVisibleAnnotations | 類,方法表,字段表 | 爲動態註解提供支持 |
RuntimeInvisibleAnnotations | 表,方法表,字段表 | 用於指明哪些註解是運行時不可見的 |
RuntimeVisibleParameterAnnotation | 方法表 | 做用與RuntimeVisibleAnnotations屬性相似,只不過做用對象爲方法 |
RuntimeInvisibleParameterAnnotation | 方法表 | 做用與RuntimeInvisibleAnnotations屬性相似,做用對象哪一個爲方法參數 |
AnnotationDefault | 方法表 | 用於記錄註解類元素的默認值 |
BootstrapMethods | 類文件 | 用於保存invokeddynamic指令引用的引導方式限定符 |
對於每一個屬性,它的名稱須要從常量池中引用一個CONSTANT_utf8_info類型的常量類表示,而屬性值的結構則是徹底自定義的,只須要經過一個u4的長度屬性區說明屬性值所佔用的位數便可.
屬性表定義的結構:
類型 | 名稱 | 數量 |
u2 | attribute_name_index | 1 |
u2 | attribute_length | 1 |
u1 | info | attribute_length |
Java程序方法體中的代碼通過Javac編譯處理後,最終變爲字節碼指令存儲在Code屬性中.Code屬性出如今方法表的屬性集合中,可是並不是全部的方法表都有這個屬性.例如接口或類中的方法就不存在Code屬性了.
在字節碼指令以後的是方法的是方法的顯式異常處理表集合,異常表對於Code屬性來講並非必須參在的.
max_stack操做數棧,max_locals局部變量表所需空間,
結構:
類型 | 名稱 | 數量 |
u2 | attribute_name_index | 1 |
u4 | attribute_length | 1 |
u2 | max_stack | 1 |
u2 | max_locals | 1 |
u4 | code_length | 1 |
u1 | code | code_length |
u2 | exception_table_length | 1 |
exception_info | exception_table | exception_length |
u2 | attributes_count | 1 |
attribute_info | attributes | attributes_count |
異常表的格式以下表所示,他包含4個字段,這些字段的含義爲:若是當字節碼在第start_pc行到end_pc行之間(不含第end_pc行)出現了類型爲catch_type或者其子類的異常(catch_type爲指向一個CONSTANT_Class_info型常量的索引),則轉到第handler_pc行繼續處理。當catch_type的值爲0時,表明任意異常狀況都須要轉向到handler_pc處進行處理。
類型 名稱 數量 類型 名稱 數量 u2 start_pc 1 u2 handler_pc 1 u2 end_pc 1 u2 catch_type 1
Exception屬性的做用是列出方法中能拋出的受查異常Check Exceptions,也就是方法描述時在throws關鍵字以後列舉的異常
結構:
類型 | 名稱 | 數量 |
u2 | attribute_name_index | 1 |
u2 | attribute_lrngth | 1 |
u2 | attribute_of_exception | 1 |
u2 | exception_index_tsble | number_of_exceptions |
Exception屬性中的number_of_exceptions項表示方法可能拋出的number_of_exceptions種受查異常,每一種受查異常使用一個exception_index_tsble項表示,exception_index_tsble是一個指向常量池中CONSTANT_Class_info型常量的索引,表明了該受查異常的類型.
結構:
類型 | 名稱 | 數量 |
u2 | attribute_name_index | 1 |
u4 | attribute_length | 1 |
u2 | line_number_table_length | 1 |
line_number_info | line_number_table | line_number_table_length |
line_number_table是一個數量爲line_number_table_length,類型爲line_number_info的集合,line_number_info表包括了start_PC和line_number兩個u2類型的數據項,前者是字節碼行號,後者是Java源代碼行號.
BoottstrapMethods(之後再看)
字節碼指令簡介:加載和存儲指令、運算指令、類型轉換指令、對象建立與訪問指令、操做數棧管理指令、控制轉移指令、方法調用和返回指、異常處理指令、同步指令