標籤:count extend nts pos ansi 實現 ima 代碼 get
Java 實現一次編譯到處啟動並執行基礎,來源於 JAVA 虛擬機器屏蔽了作業系統的底層細節。使用 class 檔案儲存體編譯後的來源程式,使得 Java 程式的編譯與作業系統解耦。正是因為 Java class 檔案的設計與 Java 語言解耦,分別發布了 Java語言規範和 JAVA 虛擬機器規範,使得其他語言如Scala、Groovy、JRuby、JPython 等基於JAVA 虛擬機器的語言按照 class 檔案格式要求產生的class 檔案也能在虛擬機器上運行。
class 檔案格式
class 檔案採用如下的結構儲存二進位內容。其中 u2、u4 分別表示佔用 2、4 個位元組。
{
u4 magic; //魔數,固定為0xCAFEBABE
u2 minor_version; //次版本號碼
u2 major_version; //主要版本號
u2 constant_pool_count; //常量池計數器
cp_info constant_pool[constant_pool_count-1]; //常量池
u2 access_flags; //訪問標誌,聲明許可權
u2 this_class; //類索引
u2 super_class; //父類索引
u2 interfaces_count; //介面個數
u2 interfaces[interfaces_count]; //介面列表
u2 fields_count; //欄位個數
field_info fields[fields_count];//欄位列表
u2 methods_count; //方法個數
method_info methods[methods_count]; //方法列表
u2 attributes_count; //屬性個數
attribute_info attributes[attributes_count]; //屬性列表
}
class 檔案內容解讀
常量池:
儲存 class 檔案用到的所有的字串常量、類名、介面名、欄位名以及其他常量。class 檔案的其他項目往往會引用常量池中的常量,因此常量池容量計數從1開始,0 用於表示其他項目不引用常量池。在常量池中主要儲存了字面量和符號引用兩大類常量,字面量主要是字串、final 類型常量值等,符號引用則包括類和介面的全限定名、欄位的名稱和描述法以及方法的名稱和描述符。在前文《 JAVA 虛擬機器類載入機制》中提到的符號引用轉換為直接引用中的符號引用就是常量池中的符號引用。
訪問標誌:
類或介面的存取權限資訊,包括 public、final、super、interface、abstract、annotation、enum 幾種屬性,以及使用 synthetic 表示非 Java 源碼產生的程式碼。
類索引:
this_class 儲存常量池中的一個索引,索引處的常量表示 class 檔案定義的類或介面。如果這是一個類,super_class 為 0 或儲存常量池中的一個索引,索引處的常量表示父類;如果這是一個介面,super_class 儲存常量池中的一個索引,索引處的常量一定是 java.lang.Object。通過 this_class 可以確定當前類的全限定名,通過 super_class 可以確定父類的全限定名。
介面列表:
如果這是一個類,儲存該類實現的介面列表,按照 implements 後的介面順序儲存;如果這是一個介面,儲存該介面的所有父介面列表,按照 extends 後的介面順序儲存。
欄位列表:
儲存類或介面聲明的變數,包括類變數和執行個體變數。描述了每個變數的資訊,包括範圍、static、final、volatile、transient、類型、名稱等。其中欄位的名稱、類型需要引用常量池中的常量來描述。
方法列表:
儲存類或介面聲明的方法,包括類方法和執行個體方法。描述了每個方法的資訊,包括訪問標誌、名稱索引、描述符索引、屬性工作表集合等。這裡僅僅儲存了方法的資訊,方法的實現代碼編譯成位元組碼後儲存在屬性工作表集合中的 “ Code ” 屬性裡面。
屬性列表:虛擬機器規範定義了大量的屬性,class 檔案、欄位列表、方法列表都可以使用屬性描述專有資訊。而屬性的名稱需要引用常量池的常量來表示。方法體中的代碼經編譯後就存放在名為 Code 的屬性中。
總結
Java 來源程式編譯後產生 class 檔案而不是二進位可執行檔,通過 JAVA 虛擬機器來解析並執行 class 檔案中的程式,實現了“一次編譯,到處運行”。在 class 檔案中,儲存了類或介面的基本資料,如版本號碼、類名、介面列表、欄位列表、方法列表等。
原文地址:Java到處啟動並執行基礎之 Class 檔案
Java到處啟動並執行基礎之 Class 檔案