寫了那么多 Java 代碼,卻不一定見過它的真面目

我們都知道那句著名的宣傳語——「一次編寫, 到處運行(Write Once, Run Anywhere)」,這是對 Java 平臺無關性的精準概括。字節(jié)碼 + JVM 使其平臺無關,與此同時也衍生出另一個無關性——語言無關性。像 Kotlin、Groovy、Scala、Clojure、JRuby 等語言都可以運行在 JVM 之上。理論上只要能將源代碼編譯成符合 JVM 規(guī)范的字節(jié)碼,任何語言都可以在 JVM 中運行。
字節(jié)碼是連接語言和 JVM 的關鍵橋梁,今天我們就一起聊聊這個關鍵人物。
概覽
我們創(chuàng)建一個 User 類:
然后通過 javac 命令編譯,得到 User.class 文件。然后用支持十六進制的文本工具(比如 sublime)打開,你會看到如下內容:

在一堆看似毫無規(guī)律的字符中,我們發(fā)現(xiàn)開頭幾個字好像有什么特別的含義——cafe babe,咖啡寶貝?沒錯,這也解釋了為啥 Java 的商標是一杯冒著熱氣的咖啡。開頭這四個字節(jié)叫做魔數(shù)(Magic Number),它的唯一作用就是確定這是一個可以被 JVM 接受的 Class 文件。
Class 文件中沒有任何分隔符, 各數(shù)據(jù)項嚴絲合縫依次排列。哪個字節(jié)代表什么含義,誰挨著誰,長度是多少,都是有規(guī)定的,不能改變。
類文件結構
先來看一個 Class 文件的標準結構:
來自《The Java Virtual Machine Specification》Java SE 8 Edition
如上所示,Class 文件中包含兩種數(shù)據(jù)類型:「無符號數(shù)」和「表」。
無符號數(shù)是基本類型,u1、 u2、 u4、 u8 分別表示 ?1 個字節(jié)、 2 個字節(jié)、 4 個字節(jié)和 8 個字節(jié)的無符號數(shù)。無符號數(shù)可以描述數(shù)字、索引引用、數(shù)量值或者按照 UTF-8 編碼的字符串。?
表是由多個無符號數(shù)或其他表組合而成(復雜對象),并且以「_info」結尾。一個 Class 文件可以視作一張表。
各數(shù)據(jù)項說明:

順序由上到下,嚴格限制,不可修改
下面用一張更形象的圖展示一下 Class 文件的結構示意:

如何查看
我們可以通過 JDK 自帶的「javap」命令來查看 Class 文件的字節(jié)碼信息:
你會看到如下信息:

另外,還可以通過 IDEA 的插件來查看,會更加友好一些。效果如下:

插件:JClassLib
結束
學習字節(jié)碼會讓之前只知其然的知識,變得知其所以然。
今天先開(挖)個?。ù螅╊^(坑),如果你對字節(jié)碼感興趣可以留言告訴我,后面我們再進行詳(慢)細(慢)討(填)論(坑)。