1. 程式人生 > >第6章 類文件結構

第6章 類文件結構

多個 ava 字節碼 中間 分割 索引 類文件 info 所有

6.1 概述

  計算機只認識0和1,傳統的語言直接交給操作系統去執行,所以他們不能像Java一樣,一次編譯到處運行。Java編譯後的代碼是由虛擬機執行,編譯後的結果是平臺中立的格式。

6.2 無關性的基石

  各種平臺下Java編譯後的格式都是一樣的,所以稱為平臺中立的,這個格式就是字節碼(Byte Code)。Java虛擬機只認識字節碼即class文件,所以虛擬機也可以執行別的語言,只要這些語言編譯後的代碼是class文件。

6.3 Class類文件的結構

  主要介紹class文件的結構,以jdk1.4為主線。

  class文件是什麽?是一組二進制字節流,其格式有著嚴格的要求必須以8字節為單位進行排列。如果需要占有的字節大於8字節就需要按照大端的方式進行分割,最高位字節在最低位。這個與x86處理器相反,x86采用最低位字節在地址最低位。這個字節碼對格式的要求非常嚴格,中間沒有分隔符。沒有分隔符怎麽能確定一個字段哪裏開頭哪裏結尾呢?所以class的結構對順序、數量都是被嚴格規定的。

  class文件的結構類似於c語言裏的結構體,由兩種數據結構組成,一種是無符號數,一種是表。無符號數用來存儲基本的數據類型的內容。表是一種復合的數據結構,由多個無符號數和別的表組成。

  技術分享圖片

6.3.1 魔數與class文件版本

  class文件開頭是魔數,是指用來判斷這個二進制文件是不是class文件的。我們平時看一個文件的類型是從擴展名來判斷,這其實不太安全,因為擴展名是可以改的。java虛擬機根據一個二進制文件的頭4個字節的內容是不是指定的內容來判斷是不是class文件。

  跟著魔數後面是class文件的版本的判斷,用來判斷class文件的版本與虛擬機的版本是不是兼容。

6.3.2 常量池

  緊接著魔數和class文件版本的就是常量池了。為什麽要有常量池呢?把所有的常量放在一個池子裏,如果一段java裏出現了兩個同樣的字符串,那麽就沒有必要加載兩次,直接再次引用即可,因為是常量,不會改變。具體而言常量池裏有兩大類的數據:1、字面量(Literal),符合我們對常量池的一般認知,放的是java裏的字符串、final修飾的變量等待。這部分內容肯定是常量。2、符號引用。從常量的角度而言,這部分也是不可改變的。有類或者接口的全限定名稱,一個字段的名稱和描述符,一個方法的字段和描述符。由於java在編譯的時候沒有鏈接這一步,引用別的方法都不能直接轉換成真實的地址,只有在運行的時候才能被翻譯成真正的入口地址,所以這部分內容要在內存裏保存下來。

  常量池第一個字段是保存了常量池裏有多少的個常量,索引從1開始。

6.3.3 訪問標誌

  用來標記這段class對應的java代碼是不是一個類,是不是一個接口,是不是抽象的等等信息。  

第6章 類文件結構