天天看點

JVM-CLASS檔案完全解析-屬性表集合

  在前面魔數,次版本号,主機闆本号,常量池入口,常量池,通路标志,類索引,父類索引,接口索引集合,字段表集合,方法表集合,那麼接下來就是屬性表集合了. 

  在class檔案,字段表,方法表都可以攜帶自己的屬性表集合(像前面方法表的時候就用到"code"這個屬性表)以用于描述某些場景專有的資訊.

  虛拟機中預定義的屬性:

屬性名稱

使用位置

含義

Code

方法表

Java代碼編譯成的位元組碼指令

ConstantValue

字段表

final關鍵字定義的常量池

Deprecated

類,方法,字段表

被聲明為deprecated的方法和字段

 Exceptions

方法表 

方法抛出的異常 

 EnclosingMethod

類檔案 

僅當一個類為局部類或者匿名類是才能擁有這個屬性,這個屬性用于辨別這個類所在的外圍方法 

 InnerClass

内部類清單 

 LineNumberTable

Code屬性 

Java源碼的行号與位元組碼指令的對應關系 

 LocalVariableTable

方法的局部便狼描述 

 StackMapTable

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

attribute_length

u1

info

  Java程式方法體中的代碼經過Javac編譯處理後,最終變為位元組碼指令存儲在Code屬性中.Code屬性出現在方法表的屬性集合中,但是并非所有的方法表都有這個屬性.例如接口或類中的方法就不存在Code屬性了.

  在位元組碼指令之後的是方法的是方法的顯式異常處理表集合,異常表對于Code屬性來說并不是必須參在的.

  結構:  

u4

max_stack

max_locals

code_length

code

exception_table_length

exception_info

exception_table

exception_length

attributes_count

attribute_info

attributes

   

  Exception屬性的作用是列出方法中能抛出的受查異常Check Exceptions,也就是方法描述時在throws關鍵字之後列舉的異常

  結構:

attribute_lrngth

attribute_of_exception

exception_index_tsble

number_of_exceptions

  Exception屬性中的number_of_exceptions項表示方法可能抛出的number_of_exceptions種受查異常,每一種受查異常使用一個exception_index_tsble項表示,exception_index_tsble是一個指向常量池中CONSTANT_Class_info型常量的索引,代表了該受查異常的類型.

line_number_table_length

line_number_info

line_number_table

  line_number_table是一個數量為line_number_table_length,類型為line_number_info的集合,line_number_info表包括了start_PC和line_number兩個u2類型的資料項,前者是位元組碼行号,後者是Java源代碼行号.

虛拟機預定義的屬性有20多個,就不意一一介紹,基本上和上述的幾個屬性差不多.

到這裡calss檔案的檔案解析也終于要告一段落了(寫了好長時間,其實我最讨厭看這些位元組碼了,其實一般程式員隻需要了解一下class檔案的構成和原理就行了,解析class檔案的工具有很多,我們可以直接看解析出來的檔案就可以了).