眾所周知,Java 語言編譯生成的 class 檔案可以運行在任何支持 Java 虛擬機的硬體平臺和作業系統上,那么,你是否思考過:class 檔案包含哪些內容?是如何在虛擬機中執行的?要弄清楚這些問題,須了解 class 檔案結構和 Java 虛擬機位元組碼指令,Java 虛擬機位元組碼指令非常重要,學習它對深入理解虛擬機、堆疊、鎖、例外、同步等的原理十分有益,是Java 進階之路必讀內容之一,
本系列一共有兩篇文章,這是第一篇,主要內容如下:
圖文解讀 class 檔案結構;
- Java 位元組碼介紹;
- 詳解 Java 虛擬機堆疊結構;
- 實體解讀 Java 虛擬機中變數、常量訪問原理和指令體系;
- 實體解讀 Java 虛擬機中物件、陣列(數值陣列、物件陣列、多維陣列)創建指令;
- 實體解讀 Java 虛擬機中方法、欄位 (又稱域-field) 訪問的原理及指令體系,
由于篇幅有限,這里只展示一部分,有需要完整版和更多相關資料的朋友可以點一點下方鏈接免費領取!
鏈接:1103806531暗號:CSDN

引言
計算機本身只能識別 0 和 1 構成的機器碼,因此,任何編程語言最終都需要編譯成機器碼才能被計算機執行,以 C/C++ 為例,用它們撰寫的程式首先被編譯,然后被連接成單獨的、支持特定硬體平臺和作業系統的二進制檔案,通常情況下,一個平臺上的二進制可執行檔案不能在其它平臺上作業,
Java 在誕生之初便提出了著名的 slogan:“Write Once, Run Anywhere”,為了實作這一目標,Java 虛擬機應運而生,目前,Java 虛擬機有很多版本,但它們都具有一個共同的特征——可以載入并執行同一種與平臺無關的位元組碼(ByteCode), 因為 Java 虛擬機的出現,Java 源代碼不必根據不同平臺編譯成 0 和 1,而是間接翻譯成位元組碼,儲存位元組碼的檔案再交由運行于不同平臺上的 Java 虛擬機去讀取執行,從而實作一次撰寫,到處運行的目的,
Java 編譯生成的位元組碼檔案為 ".class " 檔案,它是一種二進制檔案,其中包含了 Java 虛擬機指令集和符號表以及若干其它輔助資訊,作為一個通用的、機器無關的執行平臺,任何其它語言的實作者都可以將 Java 虛擬機作為語言的產品交付媒介,例如,使用 Java 編譯器可以把 Java 代碼編譯成存盤位元組碼的 class 檔案,使用 Groovy、 Scala、 Koltin 等其它語言的編譯器一樣可以把程式代碼編譯成 class 檔案,虛擬機并不關心 class 的來源是何種語言,
Class 檔案結構
class 檔案是一組以 8 位位元組位基礎單位的二進制流,采用一種類似 C 語言結構體的偽結構來存盤資料,這種偽結構只有兩種資料型別:無符號數和表,無符號數屬于基本的資料型別,以 u1、u2、u4、u8 分別代表1個位元組、2個位元組、4個位元組、8個位元組的無符號數,無符號數可以用來描述數字、索引參考、數量值或 utf-8 編碼構成的字串值,表是由多個無符號數或其它表作為資料項構成的復合資料型別,所有表都習慣性地以 _info 結尾, 每一個 class 檔案對應于一個如下所示的 ClassFile 結構體:
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; //類索引,表示這個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]; //屬性表
}
更直觀地,通過圖片來展示 class 檔案的結構,如下所示:

Class 檔案結構實體
從上面的介紹 class 檔案的結構比較復雜,事實上,我們可以將 class 檔案分為以下部分,
class檔案: 檔案描述、常量池、類概述、欄位表、方法表、擴展資訊表,為了便于讀者理解,在此,我們先來看一個實體,Java 原始碼如下:
public class Test {
private String attribute_1;
private Integer attribute_2;
public void testMethod_1() {
} public String testMethod_2(String param) {
return param;
}}
通過命令“javac Test.java”編譯后,可以得到 Test.class 檔案,這就是所謂的位元組碼檔案,Test.class 內容如下所示:

最后
希望這篇文章對大家有幫助!
我這邊也整理了一份 架構師全套視頻教程 和關于java的系統化資料,包括java核心知識點、面試專題和20年最新的互聯網真題、電子書等都有,
有需要的朋友可以點一點下方鏈接免費領取!
鏈接:1103806531暗號:CSDN


轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/76914.html
標籤:AI
