在前面魔數,次版本號,主板本號,常量池入口,常量池,訪問標誌,類索引,父類索引,接口索引集合,字段表集合,方法表集合,那麼接下來就是屬性表集合了. 程序員
在class文件,字段表,方法表均可以攜帶本身的屬性表集合(像前面方法表的時候就用到"code"這個屬性表)以用於描述某些場景專有的信息.工具
虛擬機中預約義的屬性:spa
屬性名稱 | 使用位置 | 含義 |
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的長度屬性區說明屬性值所佔用的位數便可.調試
屬性表定義的結構: code
類型 | 名稱 | 數量 |
u2 | attribute_name_index | 1 |
u2 | attribute_length | 1 |
u1 | info | attribute_length |
Java程序方法體中的代碼通過Javac編譯處理後,最終變爲字節碼指令存儲在Code屬性中.Code屬性出如今方法表的屬性集合中,可是並不是全部的方法表都有這個屬性.例如接口或類中的方法就不存在Code屬性了.對象
在字節碼指令以後的是方法的是方法的顯式異常處理表集合,異常表對於Code屬性來講並非必須參在的.索引
結構: 接口
類型 | 名稱 | 數量 |
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 |
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源代碼行號.
到這裏calss文件的文件解析也終於要告一段落了(寫了好長時間,其實我最討厭看這些字節碼了,其實通常程序員只須要了解一下class文件的構成和原理就好了,解析class文件的工具備不少,咱們能夠直接看解析出來的文件就能夠了).