激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - Java Class 解析器實現(xiàn)方法示例

Java Class 解析器實現(xiàn)方法示例

2021-01-03 15:16tinylcy Java教程

這篇文章主要通過對class文件的分析,介紹了Java Class 解析器實現(xiàn)方法示例,具有一定參考價值,需要的朋友可以了解下。

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

Class文件

作為類或者接口信息的載體,每個Class文件都完整的定義了一個類。為了使Java程序可以“編寫一次,處處運行”,Java虛擬機規(guī)范對Class文件進行了嚴格的規(guī)定。構成Class文件的基本數據單位是字節(jié),這些字節(jié)之間不存在任何分隔符,這使得整個Class文件中存儲的內容幾乎全部是程序運行的必要數據,單個字節(jié)無法表示的數據由多個連續(xù)的字節(jié)來表示。

根據Java虛擬機規(guī)范,Class文件采用一種類似于C語言結構體的偽結構來存儲數據,這種偽結構中只有兩種數據類型:無符號數和表。Java虛擬機規(guī)范定義了u1、u2、u4和u8來分別表示1個字節(jié)、2個字節(jié)、4個字節(jié)和8個字節(jié)的無符號數,無符號數可以用來描述數字、索引引用、數量值或者是字符串。表是由多個無符號數或者其它表作為數據項構成的復合數據類型,表用于描述有層次關系的復合結構的數據,因此整個Class文件本質上就是一張表。在ClassAnalyzer中,byte、short、int和long分別對應u1、u2、u4和u8數據類型,Class文件被描述為如下Java類。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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文件中都占用固定數量的字節(jié),在解析時只需要讀取相應數量的字節(jié)。除此之外,需要靈活處理的主要包括4部分:常量池、字段表集合、方法表集合和屬性表集合。字段和方法都可以具備自己的屬性,Class本身也有相應的屬性,因此,在解析字段表集合和方法表集合的同時也包含了屬性表的解析。

常量池占據了Class文件很大一部分的數據,用于存儲所有的常量信息,包括數字和字符串常量、類名、接口名、字段名和方法名等。Java虛擬機規(guī)范定義了多種常量類型,每一種常量類型都有自己的結構。常量池本身是一個表,在解析時有幾點需要注意。

每個常量類型都通過一個u1類型的tag來標識。

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

常量池的索引范圍從1開始,例如,如果constantPoolCount等于47,那么常量池的索引范圍為1~46。設計者將第0項空出來的目的是用于表達“不引用任何一個常量池項目”。

CONSTANT_Utf8_info型常量的結構中包含u1類型的tag、u2類型的length和由length個u1類型組成的bytes,這length字節(jié)的連續(xù)數據是一個使用MUTF-8(Modified UTF-8)編碼的字符串。MUTF-8與UTF-8并不兼容,主要區(qū)別有兩點:一是null字符會被編碼成2字節(jié)(0xC0和0x80);二是補充字符是按照UTF-16拆分為代理對分別編碼的,相關細節(jié)可以看這里(變種UTF-8)。

屬性表用于描述某些場景專有的信息,Class文件、字段表和方法表都有相應的屬性表集合。Java虛擬機規(guī)范定義了多種屬性,ClassAnalyzer目前實現(xiàn)了對常用屬性的解析。和常量類型的數據項不同,屬性并沒有一個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代碼編譯成的字節(jié)碼指令,在ClassAnalyzer中,Code對應的Java類如下所示(僅列出了類屬性)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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分別用于存儲字節(jié)碼長度和字節(jié)碼指令,每條指令即一個字節(jié)(u1類型)。在虛擬機執(zhí)行時,通過讀取code中的一個個字節(jié)碼,并將字節(jié)碼翻譯成相應的指令。另外,雖然codeLength是一個u4類型的值,但是實際上一個方法不允許超過65535條字節(jié)碼指令。

代碼實現(xiàn)

ClassAnalyzer的源碼已放在了GitHub上。在ClassAnalyzer的README中,我以一個類的Class文件為例,對該Class文件的每個字節(jié)進行了分析,希望對大家的理解有所幫助。

參考

深入理解Java虛擬機

結束語:以上就是本文關于如何實現(xiàn)一個Java class 解析器的全部內容,希望對大家有所幫助。

原文鏈接:https://segmentfault.com/a/1190000008328534

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 91精品观看91久久久久久国产 | 欧美激情在线播放 | 欧美在线观看视频网站 | 久久国产中文 | 欧美日韩一区,二区,三区,久久精品 | 国产91免费看 | 毛片在哪里看 | 国产视频91在线 | 成人精品免费看 | 亚久久 | 欧美一级不卡视频 | 久久九九热re6这里有精品 | 男人的天堂视频网站 | 舌头伸进添的我好爽高潮网站 | 久久成人免费网 | 亚洲一区二区三区视频免费 | 久久久三级免费电影 | 国产精品国产成人国产三级 | 日韩区在线 | 在线91视频| 青久草视频| 欧美一区二区三区成人 | 国产精品入口夜色视频大尺度 | 最新一区二区三区 | 国产91丝袜在线播放 | 91av在线免费| 日韩在线毛片 | 久久久久久久久成人 | 一级电影免费在线观看 | ⅴideo裸体秀hd | 国产成人免费精品 | 小视频成人 | 久久久久久片 | 久久久久久久久久久久久国产精品 | 31freehdxxxx欧美 | 久久最新免费视频 | 一级视频片 | 视频二区国产 | 久久国产精| 日本在线免费观看 | 男女一边摸一边做羞羞视频免费 |