<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    LetsCoding.cn

    天地之間有桿秤,拿秤砣砸老百姓。

    Java類文件的基本結構

    歡迎來到“Under The Hood”第二期。上期我們討論了抽象計算機JVM。如果你對JVM還很陌生,你可以去看看上期的文章。本期,我們稍稍窺探一下Java類文件的基本結構。

    為旅行而生

    Java類文件(.class文件)是一個為已編譯Java程序仔細定義的格式。Java源代碼被編譯成能夠被任何JVM加載和執行的類文件。在被JVM加載之前,類文件可能是由網絡傳輸而來。

    類文件是獨立于底層平臺的,所以適用于更多的地方。它們由簡潔的JVM字節碼組成,這樣就能輕裝上陣。類文件常常被壓縮,以極快的速度通過網絡,到達世界各地的JVM。

    類文件里有什么?

    Java類文件包含JVM需要知道的關于一個Java類或接口的一切。按照它們的出現次序,主要的部分有:魔法數(magic),版本號(version),常量池(constant pool),訪問標示符區(access flags),當前類區(this class),超類區(super class),父接口區(interfaces),字段區(fields),方法列表區(methods),屬性區(attributes)。

    保存在類文件中的信息經常在長度上有變化,所以信息的實際長度在被加載之前不能被預測。例如,在方法區里的方法數目,類與類之間是不相同的,這取決于源代碼中定義的方法個數。類文件中,這些信息的實際大小或長度,被安排在信息內容之前。這樣,當類文件被JVM加載時,可變信息的長度首先被讀取。一旦JVM知道信息的大小,它就能正確的讀取實際的信息內容。

    類文件中,不同的相鄰信息之間通常沒有空白或填充字符;一切都以字節(byte)邊界對齊。這使得類文件很小,適合網絡傳輸。

    為了讓JVM在加載類文件時,知道需要什么信息以及從哪里可以取得所需信息,類文件的各個組成部分的次序是嚴格定義的。例如,每個JVM都知道類文件的前8個字節由魔法數和版本號組成,常量池從第9個字節開始,訪問標示符區緊跟在常量池后面。但是,因為常量池的長度是可變的,在讀取完常量池之前,JVM是不知道訪問標示符區具體從什么地方開始。一旦讀取完常量池,JVM就知道接下來的2個字節就是訪問標示符區。

    魔法數(Magic)和版本號(Version)

    每個類文件的開始4個字節都是0xCAFEBABE。這個神奇的數字讓Java類文件更容易識別,因為類文件以外的文件幾乎不可能也以這四個相同的字節開頭。之所以稱之為魔法數,是因為它可以被文件格式設計者們從帽子里拉出來(??)。對它僅有的要求是,不能被現實已有的文件格式占用。根據最初Java團隊主要成員之一的Patrick Naughton所說,遠在“Java”被當作Java語言的名稱之前,這個神奇的數字就已經被選好了。我們當時在尋找一個有趣,獨特并且很容易記住的數字。0xCAFEBABE作為漂亮的Peet’s Coffee的咖啡師的代稱,能預示未來Java語言的名字,這完全是一個巧合。

    類文件接下來的4個字節包含了大版本號(major version)和小版本號(minor version)。這些數字標識了特定類文件使用的類文件格式,讓JVM可以驗證類文件是否可以被載入。每個JVM都有一個它能載入的最大版本號,拒絕加載大于最大版本號的類文件。

    常量池(Constant Pool)

    類文件在常量池中保存與類或接口關聯的常量。常量池中能看到的部分常量是字符串字面值(literal strings),final變量的值(final variable values),類名,接口名,變量名和變量類型,方法名和方法簽名(method names and signatures)。方法簽名由方法返回值類型(return type)和一組參數類型(argument types)組成。

    常量池被組織成一個元素長度可變的數組。每個常量占據數組中的一個元素。在整個類文件中,常量通過指示它們在數組中位置的整型索引來引用。第一個常量的索引值是1,第二個是2,以此類推。常量池數組的元素個數寫在常量池的前面,所以在加載類文件時,JVM知道它需要加載多少常量。

    常量池中每個元素以指明自己類型的單字節標簽(tag)開始。一旦JVM看到這個標簽,就能知道接下來會遇到什么類型的常量。例如,如果看到一個表示字符串的標簽,JVM會認為接下來2個字節就是字符串的長度,然后就是“長度”個字節組成的字符串。

    在本文剩下的部分,我有時會用constant_pool[n]表示常量池數組的第n個元素。從常量池組織的像個數組來說,這是有道理的;但是請記住,這些元素具有不同的大小和類型,并且第一個元素的索引是1。

    訪問標識符區(Access Flags)

    常量池之后的2個字節就是訪問標示符,它表明該文件定義的是類還是接口;該類或接口是公開的(public)還是抽象的(abstract);如果是類,該類是不是final的。

    當前類區(This class)

    接下來2個字節是當前類區,它是常量池數組的索引。被當前類引用的常量constant_pool[this_class],包含兩部分:單字節標簽(tag)和雙字節名稱索引(name index)。標簽等于CONSTANT_Class,一個表示本元素中包含類或接口信息的值。constant_pool[name_index]是一個包含類或接口名的字符串常量。

    當前類部分稍稍揭示了常量池是怎么被使用的。當前類區本身只是一個常量池的索引。當JVM查找constant_pool[this_class]時,它找到一個用標簽表明自己是一個CONSTANT_Class得元素。JVM知道CONSTANT_Class元素在標簽(tag)之后,總是有一個叫名稱索引(name index)的常量池雙字節索引。然后它查找constant_pool[name_index],得到包含類或接口名的字符串。

    超類區(Super class)

    當前類區之后是超類區,也是2個字節的常量池索引。constant_pool[super_class]是CONSTANT_Class元素,它指向當前類所直接繼承的超類名。

    接口區(Interfaces)

    接口區開頭的2個字節,表示文件所定義的類(或接口)實現的接口數目。緊接著是一個數組,它包含了類所實現的每一個接口在常量池中的索引。
    每個接口都是常量池中的CONSTANT_Class元素,它指向接口名。

    字段區(Fields)

    字段部分,以表示該類或接口包含的字段數的2個字節開始。字段是一個實例變量,或者是類或接口的類變量。接下來是一個以可變長結構為元素的數組,一個結構一個字段。每個結構都包含一個字段的相關信息,如字段名,字段類型,如果是final變量,還包括字段值。部分信息在結構當中,另一部分在常量池中由結構所指向的位置。

    這部分僅有的字段,都是由定義在該類文件中的類或接口聲明的變量;繼承自超類或接口的字段不在此列。

    方法區(Methods)

    方法部分,以表示類或接口中方法數目的2字節開始。這個數目,只包含當前類顯式定義的方法,不包括繼承自超類的方法。數目之后是方法本身。

    表示每個方法的結構包含方法相關的幾條信息,包括方法描述符(method descriptor,包括返回值類型和參數列表),方法本地變量需要的棧字(stack words)數,方法操作數棧(operand stack)需要的最大棧字數,方法捕獲的異常表,字節碼序列和行號表。

    屬性區(Attributes)

    排在最后的是屬性區,它提供定義在類文件中的特定類或接口的一般信息。屬性區以2字節的屬性數目開始,然后是屬性本身。比如一個表示源碼屬性的屬性:它表示當前類被編譯而來的源文件名。JVM會悄悄地忽略任何它們識別不了的屬性。

    本文譯自:The Java class file lifestyle

    原創文章,轉載請注明: 轉載自LetsCoding.cn
    本文鏈接地址: Java類文件的基本結構

    posted on 2014-05-19 03:49 Rolandz 閱讀(1766) 評論(2)  編輯  收藏 所屬分類: 編程實踐

    評論

    # re: Java類文件的基本結構 2014-05-19 06:36 萬利鎖業

    謝謝博主分享  回復  更多評論   

    # re: Java類文件的基本結構 2014-06-01 19:12 手賺網-手機賺錢軟件排行,手機賺錢平臺,網絡賺錢http://www.szapk.cn

    手賺網-手機賺錢軟件排行,手機賺錢平臺,網絡賺錢http://www.szapk.cn  回復  更多評論   

    導航

    統計

    留言簿(1)

    隨筆分類(12)

    隨筆檔案(19)

    積分與排名

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 亚洲第一成年免费网站| 亚洲国产精品成人久久| 亚洲欧洲国产综合AV无码久久| 97国产在线公开免费观看| 2022年亚洲午夜一区二区福利| 免费的全黄一级录像带| 亚洲AV无码成人精品区天堂| 永久免费A∨片在线观看| 亚洲国产成人久久综合碰碰动漫3d | 99久久精品毛片免费播放| 中文字幕亚洲第一| 国产一区二区三区免费观看在线| 亚洲精品字幕在线观看| 久久久免费的精品| 亚洲国产精品午夜电影| 好先生在线观看免费播放| 亚洲6080yy久久无码产自国产| 免费国产在线观看| 午夜国产精品免费观看| 亚洲国产精品久久久久秋霞影院| 可以免费看的卡一卡二| 亚洲第一综合天堂另类专| 亚洲国产午夜中文字幕精品黄网站| 国产精品偷伦视频免费观看了 | 国产精品玖玖美女张开腿让男人桶爽免费看 | 亚洲一级片在线播放| 日本无吗免费一二区| 一个人免费观看日本www视频 | 无码精品一区二区三区免费视频| 亚洲成人福利网站| 国产精品成人四虎免费视频| 4hu四虎免费影院www| 亚洲国产综合精品中文第一区 | 中文字幕久无码免费久久| 亚洲美女精品视频| 免费一看一级毛片| 小日子的在线观看免费| 亚洲AV成人精品一区二区三区| 亚洲情综合五月天| 妞干网在线免费观看| 免费毛片在线看不用播放器 |