1 JVM的“平台無關性”
Java具有平台無關性,即任何作業系統都能運作Java代碼。
之是以能實作這一點,是因為Java運作在虛拟機之上,不同的作業系統都擁有各自的Java虛拟機,是以Java能實作"一次編寫,處處運作"。
而JVM不僅具有平台無關性,還具有語言無關性:
- 平台無關性是指不同作業系統都有各自的JVM
- 語言無關性是指Java虛拟機能運作除Java以外的代碼!
但JVM對能運作的語言是有嚴格要求的。首先來了解下Java代碼的運作過程:
Java源代碼首先需要使用Javac編譯器編譯成class檔案,然後啟動JVM執行class檔案,進而程式開始運作。
即JVM隻認識class檔案,它并不管何種語言生成了class檔案,隻要class檔案符合JVM的規範就能運作。
是以目前已經有Scala、JRuby、Jython等語言能夠在JVM上運作。它們有各自的文法規則,不過它們的編譯器都能将各自的源碼編譯成符合JVM規範的class檔案,進而能夠借助JVM運作它們。

Class檔案是JVM的輸入, Java虛拟機規範中定義了Class檔案的結構。Class檔案是JVM實作平台無關、技術無關的基礎。
2 縱觀Class檔案結構
class檔案包含Java程式執行的位元組碼,資料嚴格按照格式緊湊排列在class檔案中的二進制流,中間無任何分隔符。
檔案開頭有一個0xcafebabe(16進制)特殊的一個标志。
- 下圖展示為16進制
class檔案是一組以8位元組為機關的二進制位元組流,對于占用空間大于8位元組的資料項,按照高位在前的方式分割成多個8位元組進行存儲。
它的内容具有嚴格的規範,檔案中沒有任何分隔符,全是連續的0/1。
class檔案中的所有内容被分為兩種類型:
-
無符号數
基本的資料類型,以u1、u2、u4、u8,分别代表1位元組、2位元組、4位元組、8位元組的無符号數
-
表
class檔案中所有資料(即無符号數)要麼單獨存在,要麼由多個無符号數組成二維表.即class檔案中的資料要麼是單個值,要麼是二維表.通常以_info 結尾
檔案格式
javap工具生成非正式的"虛拟機彙編語言” ,格式如下:
<index> <opcode> [<operand1> [<operand2> ...]][<comment>]
-
是指令操作碼在數組中的下标,該數組以位元組形式來存儲目前方法的Java虛拟機代碼;也可以是相對于方法起始處的位元組偏移量<index>
-
是指令的助記碼<opcode>
-
是操作數< operand>
-
是行尾的注釋<comment>
ClassFile {
u4 magic;
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];
}
實踐
- Demo1.java
Demo1.txt
版本号規則: JDK5,6,7,8
分别對應49,50,51,52
2.1 魔數(Magic Number)
class檔案的頭4個位元組稱為魔數,唯一作用是确定這個檔案是否為一個能被JVM接受的Class檔案.
作用就相當于檔案字尾名,隻不過字尾名容易被修改,不安全.
是用16進制表示的"CAFEBABE".
2.2 版本資訊
緊接着魔數的4個位元組是版本号.它表示本class中使用的是哪個版本的JDK.
在高版本的JVM上能夠運作低版本的class檔案,但在低版本的JVM上無法運作高版本的class檔案.