在 Java 中,JVM 能夠理解的代碼就叫作字節碼
(即擴展名爲 .class
的文件),它不面向任何特定的處理器,只面向虛擬機。Java 語言經過字節碼的方式,在必定程度上解決了傳統解釋型語言執行效率低的問題,同時又保留了解釋型語言可移植的特色。因此 Java 程序運行時比較高效,並且,因爲字節碼並不針對一種特定的機器,所以,Java 程序無須從新編譯即可在多種不一樣操做系統的計算機上運行。java
Class文件字節碼結構組織示意圖 編碼
緊接着主次版本號以後的是常量池,常量池的數量是 constant_pool_count-1(常量池計數器是從1開始計數的,將第0項常量空出來是有特殊考慮的,索引值爲0表明「不引用任何一個常量池項」)。spa
常量池主要存放兩大常量:字面量和符號引用。字面量比較接近於 Java 語言層面的的常量概念,如文本字符串、聲明爲 final 的常量值等。而符號引用則屬於編譯原理方面的概念。包括下面三類常量:類和接口的全限定名 字段的名稱和描述符 方法的名稱和描述符操作系統
常量池中每一項常量都是一個表,這14種表有一個共同的特色:開始的第一位是一個 u1 類型的標誌位 -tag 來標識常量的類型,表明當前這個常量屬於哪一種常量類型.code
類型 | 標誌(tag) | 描述 |
---|---|---|
CONSTANT_utf8_info | 1 | UTF-8編碼的字符串 |
CONSTANT_Integer_info | 3 | 整形字面量 |
CONSTANT_Float_info | 4 | 浮點型字面量 |
CONSTANT_Long_info | 5 | 長整型字面量 |
CONSTANT_Double_info | 6 | 雙精度浮點型字面量 |
CONSTANT_Class_info | 7 | 類或接口的符號引用 |
CONSTANT_String_info | 8 | 字符串類型字面量 |
CONSTANT_Fieldref_info | 9 | 字段的符號引用 |
CONSTANT_Methodref_info | 10 | 類中方法的符號引用 |
CONSTANT_InterfaceMethodref_info | 11 | 接口中方法的符號引用 |
CONSTANT_NameAndType_info | 12 | 字段或方法的符號引用 |
CONSTANT_MothodType_info | 16 | 標誌方法類型 |
CONSTANT_MethodHandle_info | 15 | 表示方法句柄 |
CONSTANT_InvokeDynamic_info | 18 | 表示一個動態方法調用點 |
4.在常量池結束以後,緊接着的兩個字節表明訪問標誌,這個標誌用於識別一些類或者接口層次的訪問信息,包括:這個 Class 是類仍是接口,是否爲 public 或者 abstract 類型,若是是類的話是否聲明爲 final 等等。blog
5.類索引用於肯定這個類的全限定名,父類索引用於肯定這個類的父類的全限定名,因爲 Java 語言的單繼承,因此父類索引只有一個,除了 java.lang.Object
以外,全部的 java 類都有父類,所以除了 java.lang.Object
外,全部 Java 類的父類索引都不爲 0。繼承
接口索引集合用來描述這個類實現了那些接口,這些被實現的接口將按implents
(若是這個類自己是接口的話則是extends
) 後的接口順序從左到右排列在接口索引集合中。索引
6.字段表(field info)用於描述接口或類中聲明的變量。字段包括類級變量以及實例變量,但不包括在方法內部聲明的局部變量。接口
field info(字段表) 的結構:ip
public
,private
,protected
修飾符),是實例變量仍是類變量(static
修飾符),能否被序列化(transient 修飾符),可變性(final),可見性(volatile 修飾符,是否強制從主內存讀寫)。上述這些信息中,各個修飾符都是布爾值,要麼有某個修飾符,要麼沒有,很適合使用標誌位來表示。而字段叫什麼名字、字段被定義爲何數據類型這些都是沒法固定的,只能引用常量池中常量來描述。
7.方法表集合