搜尋
首頁Javajava教程Java實作Class解析器的方法範例

Java實作Class解析器的方法範例

Sep 15, 2017 am 10:16 AM
classjava方法

這篇文章主要透過對class檔案的分析,介紹了Java Class 解析器實作方法範例,具有一定參考價值,需要的朋友可以了解下。

最近在寫一個私人項目,名字叫做ClassAnalyzer,ClassAnalyzer的目的是能讓我們對Java Class文件的設計與結構能夠有一個深入的理解。主體框架與基本功能已經完成,還有一些細節功能日後再增加。實際上JDK已經提供了命令列工具javap來反編譯Class文件,但本篇文章將闡明我實作解析器的思路。

Class檔案

作為類別或介面資訊的載體,每個Class檔案都完整的定義了一個類別。為了使Java程式可以“編寫一次,處處運行”,Java虛擬機規範對Class檔案進行了嚴格的規定。構成Class檔案的基本資料單位是字節,這些位元組之間不存在任何分隔符,這使得整個Class檔案中儲存的內容幾乎全部是程式運行的必要數據,單一位元組無法表示的資料由多個連續的位元組來表示。

根據Java虛擬機器規範,Class檔案採用一種類似C語言結構體的偽結構來儲存數據,這種偽結構中只有兩種資料類型:無符號數和表。 Java虛擬機規格定義了u1、u2、u4和u8來分別表示1個位元組、2個位元組、4個位元組和8個位元組的無符號數,無符號數可以用來描述數字、索引引用、數量值或者是字串。表是由多個無符號數或其它表作為數據項構成的複合數據類型,表用於描述有層次關係的複合結構的數據,因此整個Class文件本質上就是一張表。在ClassAnalyzer中,byte、short、int和long分別對應u1、u2、u4和u8資料類型,Class檔案被描述為如下Java類別。


public class ClassFile {
 public U4 magic;       // magic
 public U2 minorVersion;      // minor_version
 public U2 majorVersion;      // major_version
 public U2 constantPoolCount;    // constant_pool_count
 public ConstantPoolInfo[] cpInfo;   // cp_info
 public U2 accessFlags;      // access_flags
 public U2 thisClass;      // this_class
 public U2 superClass;      // super_class
 public U2 interfacesCount;     // interfaces_count
 public U2[] interfaces;      // interfaces
 public U2 fieldsCount;      // fields_count
 public FieldInfo[] fields;     // fields
 public U2 methodsCount;      // methods_count
 public MethodInfo[] methods;    // methods
 public U2 attributesCount;     // attributes_count
 public BasicAttributeInfo[] attributes;  // attributes
}

如何解析

#組成Class檔案的各個資料項目中,例如魔數、Class檔案的版本等資料項目、存取標誌、類別索引、父類別索引,它們在每個Class檔案中都佔用固定數量的字節,在解析時只需要讀取對應數量的位元組。除此之外,需要靈活處理的主要包括4部分:常數池、欄位表集合、方法表集合、屬性表集合。欄位和方法都可以具備自己的屬性,Class本身也有對應的屬性,因此,在解析欄位表集合和方法表集合的同時也包含了屬性表的解析。

常數池佔據了Class檔案很大一部分的數據,用於儲存所有的常數信息,包括數字和字串常數、類別名稱、介面名、欄位名稱和方法名稱等。 Java虛擬機器規格定義了多種常數類型,每種常數類型都有自己的結構。常量池本身就是一個表,在解析時有幾點要注意。

每個常數類型都透過一個u1類型的tag來標識。

表頭給出的常數池大小(constantPoolCount)比實際大1,例如,如果constantPoolCount等於47,那麼常數池中有46項常數。

常數池的索引範圍從1開始,例如,如果constantPoolCount等於47,那麼常數池的索引範圍為1~46。設計者將第0項空出來的目的是用來表達「不引用任何一個常數池項目」。

CONSTANT_Utf8_info型常數的結構中包含u1類型的tag、u2類型的length和由length個u1類型組成的bytes,這length位元組的連續資料是一個使用MUTF-8(Modified UTF-8)編碼的字串。 MUTF-8與UTF-8並不相容,主要差異有兩點:一是null字元會被編碼成2位元組(0xC0和0x80);二是補充字元是依照UTF-16拆分為代理對分別編碼的,相關細節可以看這裡(變種UTF-8)。

屬性表用於描述某些場景專有的信息,Class檔案、欄位表和方法表都有對應的屬性表集合。 Java虛擬機器規格定義了多種屬性,ClassAnalyzer目前實作了對常用屬性的解析。和常數類型的資料項目不同,屬性並沒有一個tag來識別屬性的類型,但是每個屬性都包含有一個u2類型的attribute_name_index,attribute_name_index指向常數池中的一個CONSTANT_Utf8_info類型的常數,該常數包含著屬性的名稱。在解析屬性時,ClassAnalyzer正是透過attribute_name_index所指向的常數對應的屬性名稱來得知屬性的類型。

欄位表格用於描述類別或介面中宣告的變數,欄位包括類別層級變數以及實例層級變數。欄位表的結構包含一個u2類型的access_flags、一個u2類型的name_index、一個u2類型的descriptor_index、一個u2類型的attributes_count和attributes_count個attribute_info類型的attributes。我們已經介紹了屬性表的解析,attributes的解析方式與屬性表的解析方式一致。

Class的文件方法表采用了和字段表相同的存储格式,只是access_flags对应的含义有所不同。方法表包含着一个重要的属性:Code属性。Code属性存储了Java代码编译成的字节码指令,在ClassAnalyzer中,Code对应的Java类如下所示(仅列出了类属性)


public class Code extends BasicAttributeInfo {
 private short maxStack;
 private short maxLocals;
 private long codeLength;
 private byte[] code;
 private short exceptionTableLength;
 private ExceptionInfo[] exceptionTable;
 private short attributesCount;
 private BasicAttributeInfo[] attributes;
 ...
 private class ExceptionInfo {
  public short startPc;
  public short endPc;
  public short handlerPc;
  public short catchType;
   ...
 }
}

在Code属性中,codeLength和code分别用于存储字节码长度和字节码指令,每条指令即一个字节(u1类型)。在虚拟机执行时,通过读取code中的一个个字节码,并将字节码翻译成相应的指令。另外,虽然codeLength是一个u4类型的值,但是实际上一个方法不允许超过65535条字节码指令。

代码实现

ClassAnalyzer的源码已放在了GitHub上。在ClassAnalyzer的README中,我以一个类的Class文件为例,对该Class文件的每个字节进行了分析,希望对大家的理解有所帮助。

以上是Java實作Class解析器的方法範例的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
Java開發的哪些方面取決於平台?Java開發的哪些方面取決於平台?Apr 26, 2025 am 12:19 AM

JavadevelovermentIrelyPlatForm-DeTueTososeVeralFactors.1)JVMVariationsAffectPerformanceNandBehaviorAcroSsdifferentos.2)Nativelibrariesviajnijniiniininiinniinindrododerplatefform.3)

在不同平台上運行Java代碼時是否存在性能差異?為什麼?在不同平台上運行Java代碼時是否存在性能差異?為什麼?Apr 26, 2025 am 12:15 AM

Java代碼在不同平台上運行時會有性能差異。 1)JVM的實現和優化策略不同,如OracleJDK和OpenJDK。 2)操作系統的特性,如內存管理和線程調度,也會影響性能。 3)可以通過選擇合適的JVM、調整JVM參數和代碼優化來提升性能。

Java平台獨立性有什麼局限性?Java平台獨立性有什麼局限性?Apr 26, 2025 am 12:10 AM

Java'splatFormentenceHaslimitations不包括PerformanceOverhead,versionCompatibilityIsissues,挑戰WithnativelibraryIntegration,Platform-SpecificFeatures,andjvminstallation/jvminstallation/jvmintenance/jeartenance.therefactorscomplicatorscomplicatethe“ writeOnce”

解釋平台獨立性和跨平台發展之間的差異。解釋平台獨立性和跨平台發展之間的差異。Apr 26, 2025 am 12:08 AM

PlatformIndependendecealLowsProgramStormonanyPlograwsStormanyPlatFormWithOutModification,而LileCross-PlatFormDevelopmentRequiredquiresMomePlatform-specificAdjustments.platFormIndependence,EneblesuniveByjava,EnablesuniversUniversAleversalexecutionbutmayCotutionButMayComproMisePerformance.cross.cross.cross-platformd

即時(JIT)彙編如何影響Java的性能和平台獨立性?即時(JIT)彙編如何影響Java的性能和平台獨立性?Apr 26, 2025 am 12:02 AM

JITcompilationinJavaenhancesperformancewhilemaintainingplatformindependence.1)Itdynamicallytranslatesbytecodeintonativemachinecodeatruntime,optimizingfrequentlyusedcode.2)TheJVMremainsplatform-independent,allowingthesameJavaapplicationtorunondifferen

為什麼Java是開發跨平台桌面應用程序的流行選擇?為什麼Java是開發跨平台桌面應用程序的流行選擇?Apr 25, 2025 am 12:23 AM

javaispopularforcross-platformdesktopapplicationsduetoits“ writeonce,runany where”哲學。 1)itusesbytiesebyTecodeThatrunsonAnyJvm-備用Platform.2)librarieslikeslikeslikeswingingandjavafxhelpcreatenative-lookingenative-lookinguisis.3)

討論可能需要在Java中編寫平台特定代碼的情況。討論可能需要在Java中編寫平台特定代碼的情況。Apr 25, 2025 am 12:22 AM

在Java中編寫平台特定代碼的原因包括訪問特定操作系統功能、與特定硬件交互和優化性能。 1)使用JNA或JNI訪問Windows註冊表;2)通過JNI與Linux特定硬件驅動程序交互;3)通過JNI使用Metal優化macOS上的遊戲性能。儘管如此,編寫平台特定代碼會影響代碼的可移植性、增加複雜性、可能帶來性能開銷和安全風險。

與平台獨立性相關的Java開發的未來趨勢是什麼?與平台獨立性相關的Java開發的未來趨勢是什麼?Apr 25, 2025 am 12:12 AM

Java將通過雲原生應用、多平台部署和跨語言互操作進一步提昇平台獨立性。 1)雲原生應用將使用GraalVM和Quarkus提升啟動速度。 2)Java將擴展到嵌入式設備、移動設備和量子計算機。 3)通過GraalVM,Java將與Python、JavaScript等語言無縫集成,增強跨語言互操作性。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

將Eclipse與SAP NetWeaver應用伺服器整合。

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

強大的PHP整合開發環境

MantisBT

MantisBT

Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )專業的PHP整合開發工具