關鍵字: class
Fields_count 和 fields
緊接著 interfaces 后面的是對該類或者接口中所生命的字段的描述。首先是計數 fields_count ,它是類變量和實例變量的字段的數量總和。在這個計數后面有相應數目個 field_info 表。此表包含了字段的名字、描述符和修飾符。如果該字段被聲明為 final , field_info 還會展示其常量值。
圖 2 : field_info 表的格式
自上而下分別為:訪問標志,簡單名稱(非全限定名),字段描述符,屬性。字段描述符即該字段的型別。
方法表與方法表計數。方法表的格式與 field_info 類似,區別在于其描述的是方法。故不再贅述。
Java 虛擬機實現定義了兩種屬性 ----SourceCode 和 InnerClasses ,它們出現在 ClassFile 表中的屬性列表中。
Class 的生命周期
Java 虛擬機通過裝載、連接和初始化一個 java 類型,使該類型可以被正在運行的 java 程序所使用。其中,裝載就是把二進制形式的 java 類型讀入 java 虛擬機中;而連接就是把這種已經讀入虛擬機的二進制形式的類型數據合并到虛擬機的運行時狀態中。連接階段分為三個子步驟 ----- 驗證、準備、解析。“驗證”確保了 java 類型數據格式正確并且適于 java 虛擬機的使用。而“準備”步驟則負責為該類型分配它所需的內存,比如為它的類變量分配內存。“解析”步驟則負責把常量池中的符號引用轉換為直接引用。
圖 3 :類型生命周期的開始
裝載
要裝載一個類型, java 虛擬機必須:
通過該類型的完全限定名,產生一個代表該類型的二進制數據流
解析這個二進制數據流為方法去內的內部數據結構
創建一個俄表示該類型的 java.lang.Class 類的實例
裝載步驟的最終產品就是一個 java.lang.Class 的實例對象,而這個對象就是該類型在虛擬機中的“注冊”,要訪問該類型的信息,程序就要調用該類型對應的 class 實例對象的方法。
所有類都由類裝載器載入,載入內存中的類對應一個 java.lang.Class 實例。存在一個 Bootstrap Loader (以下簡稱為 BL ),由 C++ 寫成,負責在虛擬機啟動后一次性加載 Java 基礎類庫中的所有類。其他的類裝載器由 java 寫成,都是 java.lang.ClassLoader 的子類。除 BL 之外的所有類裝載器都有一個 parent 屬性,指向其父裝載器。
用戶自定義的類裝載器是 java.lang.ClassLoader 的子類的實例,它以定制的方式裝入類。
裝載一個類時,首先要裝載該類的基類及其接口
Java 基礎類由 BL 在虛擬機啟動時一次性載入
包含 main() 的入口類由 AL 的 loadClass() 方法載入。
由 new 關鍵字創建一個類的實例。該類由運行時刻包含該 new 語句的類實例的類裝載器( ClassLoader.getCallerClassLoader() )的 loadClass() 方法載入
連接
驗證
連接過程的第一步是驗證 - 確認類型符合 JAVA 語言的語義,并且它不會危及虛擬機的完整性。確保每個 final 類不含有子類, final 方法不能被覆蓋,以及常量池中所有的域引用和方法引用有有效的名字和類型描述符號。
準備
JAVA 虛擬機為類變量分配內存,設置默認初始值(非初始化時的默認值)。
解析
初始化
在初始化階段, Java 虛擬機設計者需要將類變量賦予正確的初始值。 <clinit> 方法:類變量初始化語句與靜態初始化塊