一文讀懂JAVA類文件結構

2021-02-19 瞎雞兒扯

前言:為什麼要學習類文件結構呢?

有些人說了類文件結構我們知道或者不知道沒有什麼作用,如果你持有這種觀點,我覺得需要矯正一下,類文件結構是沒有多大的作用,但是它是我們代碼和java虛擬機之間的橋梁,如果研究透了類文件結構,那麼會對我們研究虛擬機的運行起到至關重要的作用,同樣對於我們研究jvm內存調優能夠帶來很大的幫助。

定義: Class文件是一組以8個字節為基礎的單位的二進位流

項目嚴格按照順序緊湊的排列在文件中,沒有添加任何分隔符,這使得整個Class文件中的存儲的內容幾乎全部是程序運行的必要數據,沒有空隙存在。

數據類型: 無符號數和表

通過以上定義,我們可知,其實我們編寫的java文件,經過javac編譯之後的class文件會以一種二進位流的方式存在,這樣就方便java虛擬機來讀取我們編寫的java文件。

    也就是說class文件只是一種中介,但是這種中介的格式或者順序都是被嚴格限定的,那麼,我們的java文件變成class文件之後,會變成一種什麼樣的數據結構呢?下面我們通過一張圖來看看。

通過這張圖,我們可以從宏觀的意義上了解了一個class文件具體是怎樣組成的,那麼,下面我們分別看看,每一個組成的部分又代表了什麼?

1 魔數和JDK版本

這個不是我們代碼中已經有的,而是java虛擬機為了兼容所有的語言運行的一種設計方式,比如 我們的java版本的魔數為0xCAFEBABE,他就是固定代表著java語言,如果改了就是不行,至於JDK的版本號,裡面包括大版本號和小版本號,這樣能夠檢測我們的JDK是否支持這個class文件。

2 常量池

 常量池是一種表類型的數據項目,如類級別的字面量,final String a ="123",另外還包含符號引用,比如包名,類的全名,欄位的名稱和描述,方法的名稱和描述。

常量池可以存放22種數據類型,但是第0項被設計者作為特殊的使用,所以常量池中只能有21項常量,目前設計者已經使用了17種數據類型的常量。如CONSTANT_Utf8_info代表utf-8編碼的字符串,CONSTANT_Integer_info 代表整型字面量等。

3 訪問標誌

訪問標誌用於識別一些類或者接口的訪問信息,包括這個class是類還是接口,是否被定義為public類,是否定義為abstract類型,如果是類的話,是否被聲明final。

4 類索引、父類索引和接口索引集合

這個顧名思義就是表示類的全名,父類的全名以及接口集合的全名

5 欄位表的集合

即不包括方法內部聲明的局部變量的欄位是否為public 、private、protected、static、final等。

對於數組類型,每一維將使用一個前置的  [  字符來描述。如一個整型數組int[] 將被記錄為[I

6 方法表的集合

方法表的集合基本上和欄位表的集合一樣,描述方法是否為ublic 、private、protected、static等屬性,但是多了synchronized等屬性。

寫到這裡,大家就開始有疑問了,方法裡的java代碼跑哪裡去了呢? 這個就要說說屬性表集合了。

從使用位置來說,屬性表是一個比較雜亂的集合,包括方法表、類以及欄位表中都使用了屬性表。

比如方法表中的Code屬性,它是java編譯成的字節碼指令,如iadd等表示相加的功能,值得注意的是這些都是在棧中操作的指令,因而這種被歸屬於方法表的集合,再比如LineNumberTable屬於code屬性,其代表的含義為java源碼與字節碼指令的對應關係,這個就可以解釋為什麼異常能夠發現哪一行報錯了,再比如ContantValue屬於欄位表,他代表由final修飾的常量值。

通過以上探討,我們從宏觀上總結了java的類文件結構,相信看過的朋友能夠對類文件有一個大致的了解,進而對比如字節碼指令等問題能夠進行更深層次的探討。

相關焦點

  • 一文讀懂 DEX 文件格式解析
    我想說的是寫個解析腳本不是為了模仿著 apktools 造輪子,而是在解析過程中尋找逆向的道路,方法會變,工具會變,但一切都建立在 dex 上的安卓不會變一、什麼是 Dex 文件dex 文件是 Android 平臺上可執行文件的一種文件類型。它的文件格式可以下面這張圖概括:
  • Java File類(文件操作類)詳解
    在 Java 中,File 類是 java.io 包中唯一代表磁碟文件本身的對象,也就是說,如果希望在程序中操作文件和目錄,則都可以通過 File
  • 一文讓你明白 Java 字節碼
    Java號稱是一門「一次編譯到處運行」的語言,但是我們對這句話的理解深度又有多少呢?從我們寫的java文件到通過編譯器編譯成java字節碼文件(也就是.class文件),這個過程是java編譯過程;而我們的java虛擬機執行的就是字節碼文件。不論該字節碼文件來自何方,由哪種編譯器編譯,甚至是手寫字節碼文件,只要符合java虛擬機的規範,那麼它就能夠執行該字節碼文件。
  • 夯實Java基礎系列16:一文讀懂Java IO流和常見面試題
    ,我會試著給出Java IO(java.io)包下所有類的概述。通過編寫包裝了標準流的類,可以實現你想要的效果和過濾器。IO文件在Java應用程式中,文件是一種常用的數據源或者存儲數據的媒介。所以這一小節將會對Java中文件的使用做一個簡短的概述。這篇文章不會對每一個技術細節都做出解釋,而是會針對文件存取的方法提供給你一些必要的知識點。
  • 跟我學java編程—Java簡單條件結構
    在D盤Java目錄下,新建「ConditionSample1.java」文件。用記事本打開「ConditionSample1.java」文件,輸入以下代碼:代碼結構分析程序功能主要是演示if語句的使用。
  • 跟我學java編程—Java的Scanner類
    Scanner scanner = new Scanner(System.in);示例1:Scanner類的初始化在D盤Java目錄下,新建「ScannerInitSample.java」文件。用記事本打開「ScannerInitSample.java」文件,輸入以下代碼:代碼結構分析程序功能主要是演示Scanner如何聲明及初始化。語句「import java.util.*;」,用於導入包含Scanner的類庫,Scanner包含在Java 核心類庫util中,要使用Scanner類,必須導入java.util庫,類庫導入關鍵字為import。
  • Java Web安全 || Java基礎 · Java IO/NIO多種讀寫文件方式
    我們通常讀寫文件都是使用的阻塞模式,與之對應的也就是java.io.FileSystem。java.io.FileInputStream類提供了對文件的讀取功能,Java的其他讀取文件的方法基本上都是封裝了java.io.FileInputStream類,比如:java.io.FileReader。
  • 一文讀懂電容傳感器
    藍色標題,獲取文章】 10、一文讀懂光纖傳感器 11、一文讀懂溫溼度傳感器 12
  • 這一次,徹底弄懂 Java 字節碼文件!
    前面都是鋪墊,來到重磅分析的一節。Java字節碼整體結構如下圖所示,以下圖示以不同緯度展示了字節碼結構中所包含的關鍵內容。Java字節碼整體結構圖:完整的Java字節碼結構圖:接下來結合十六進位格式的 class 文件,參照 Java字節碼文件來剖析下都包含了哪些內容。
  • Java文件操作——XML文件的讀取
    閱讀目錄一、邂逅XML文件種類是豐富多彩的,XML作為眾多文件類型的一種,經常被用於數據存儲和傳輸。所以XML在現今應用程式中是非常流行的。本文主要講Java解析和生成XML。用於不同平臺、不同設備間的數據共享通信。
  • Java讀取和寫入txt文件
    1 問題描述對於java的讀取和寫入txt一直心存疑惑,隨著知識的積累,又重新進行學習,對java的文件讀寫理解更加深刻,在這裡將自己的小小經驗總結分享給大家。下面是大家了解java流的一個基本框架。2 問題分析在java中,java的讀寫操作(輸入輸出)可以用「流」這個概念來表示,輸入和輸出功能是Java對程序處理數據能力的提高, java的讀寫操作又分為兩種:字符流和字節流。Java以流的形式處理數據。流是一組有序的數據序列,根據操作的類型,分為輸入流和輸出流。
  • 跟我學java編程—Java的switch結構
    Java語言提供了另一種用於多分支選擇的switch結構。如果程序必須進行很多的判斷,而且所有判斷都取決於同一變量的值,則建議使用switch結構代替一系列的if-else-if結構。該default語句不是必選項,但如果不指定該語句,在任何情況都不滿足的情況下,整個switch結構不做任何操作。
  • cmd命令行 編譯Java 文件
    【注2】基本的編譯命令以下主要分為兩種說明:一、最簡單的類,僅包含main函數因為就是單純的Java文件格式,即格式: 包名.Java文件名//示例如下:該情況的編譯方法如下:方式一:cmd,找到文件所在目錄,輸入以下命令(後面是空白,不報錯一般就是編譯成功了)
  • java類加載的過程概述
    加載:是將class文件讀入內存,並為之創建一個Class對象。任何類被使用時系統都會建立一個Class對象。2. 連接:(1)驗證是否有正確的內部結構,並和其他類協調一致。(2)準備負責為類的靜態成員分配內存,並設置默認初始化值。(3)解析將類的二進位數據中的符號引用替換為直接。
  • 跟我學java編程—Java多重if結構
    前面一節已經討論了簡單的條件結構。條件結構用於實現需要判斷的情況,它以一個邏輯條件成立與否為條件,決定一個操作的執行或不執行,或執行兩個不同的操作。上節介紹的if和if-else結構,它是Java語言中實現判斷的兩種方法,可以實現一個邏輯條件的判斷。
  • 零基礎學習初識Java筆記
    在當前目錄下 輸入 javac 文件名.java,這是編譯5.java 文件名,這是運行javac 是編譯命令java 是運行命令javac HelloWorld.java 會把HelloWorld.java 這個文件
  • 一文讀懂 Java 字符串相關知識點和常見面試題
    作者:黃小斜來源:微信公眾號【黃小斜】目錄string基礎Java String 類創建字符串StringDemo.java 文件代碼:String基本用法創建String對象的常用方法String中常用的方法
  • 獨家 | 一文讀懂Hadoop(三):Mapreduce
    讀者可以通過閱讀「一文讀懂Hadoop」系列文章,對Hadoop技術有個全面的了解,它涵蓋了Hadoop官網的所有知識點,並且通俗易懂,英文不好的讀者完全可以通過閱讀此篇文章了解Hadoop。本期獨家內容「一文讀懂Hadoop」系列文章先介紹Hadoop,繼而分別詳細介紹HDFS、MAPREDUCE、YARN的所有知識點,分為四期內容在近幾天推送。敬請關注後續內容。
  • 深入理解Java虛擬機:類加載機制
    虛擬機把描述類的數據從Class文件加載到內存,並對數據進行校驗,解析和初始化,最終形成可以被虛擬機直接使用的Java類型。一、類的生命周期二、類加載時機必須對類進行"初始化"的情況:使用new關鍵字實例化對象的時候讀取或設置一個類型的靜態欄位(被final修飾、已在編譯期把結果放入常量池的靜態欄位除外)的時候。
  • JVM之用Java解析class文件
    《深入理解java虛擬機》中花了一整個章節來講解Class文件,可是看完後,一直都還是迷迷糊糊,似懂非懂。正好前段時間看見一本書很不錯:《自己動手寫Java虛擬機》,作者利用go語言實現了一個簡單的JVM,雖然沒有完整實現JVM的所有功能,但是對於一些對JVM稍感興趣的人來說,可讀性還是很高的。