- Java虛擬機字節碼:從入門到實戰
- 吳就業
- 602字
- 2021-01-08 19:08:27
解析this與super
在Class文件結構中,緊挨著訪問標志access_flags項的是this_class和super_class這兩項,也都是U2類型。this_class存儲的是常量池中某項常量的索引,super_class要么為0,要么也是存儲常量池中某項常量的索引[1]。this_class和super_class指向的常量必須是一個CONSTANT_Class_info結構的常量。
只有Object類的super_class可以為0,接口的super_class指向常量池中Object類的CONSTANT_Class_info常量。
this_class與super_class的解析器實現非常簡單,如代碼清單2-37所示。
代碼清單2-37 this_class與super_class解析器
public class ThisAndSuperClassHandler implements BaseByteCodeHandler { @Override public int order() { return 4; } @Override public void read(ByteBuffer codeBuf, ClassFile classFile) throws Exception { classFile.setThis_class(new U2(codeBuf.get(), codeBuf.get())); classFile.setSuper_class(new U2(codeBuf.get(), codeBuf.get())); } }
由于該項目已經完成了常量池的解析,在解析獲取到this_class與super_class之后,我們就可以先根據this_class的值到常量池取得對應的CONSTANT_Class_info常量,再從取得的CONSTANT_Class_info常量中獲取該常量的name_index的值,最后根據name_index再回到常量池中取得對應的CONSTANT_Utf8_info常量,這樣就能獲取到具體的類名了。該過程描述如圖2.6所示。

圖2.6 獲取this_class指向的類名
現在我們編寫單元測試驗證this與super解析器。為了直觀的顯示解析結果,我們需要在單元測試用例中,將解析后的this_class與super_class指向的CONSTANT_Class_info常量轉為CONSTANT_Utf8_info常量,直接輸出字符串類名。如代碼清單2-38所示。
代碼清單2-38 this與super解析器單元測試
public class ThisAndSuperHandlerTest { @Test public void testThisAndSuperHandlerHandler() throws Exception { ByteBuffer codeBuf = ClassFileAnalysisMain.readFile("RecursionAlgorithmMain.class"); ClassFile classFile = ClassFileAnalysiser.analysis(codeBuf); // this_class U2 this_class = classFile.getThis_class(); // 根據this_class到常量池獲取CONSTANT_Class_info常量 // 由于常量池的索引是從1開始的,所以需要將索引減1取得數組下標 CONSTANT_Class_info this_class_cpInfo = (CONSTANT_Class_info) classFile.getConstant_pool()[this_class.toInt() - 1]; CONSTANT_Utf8_info this_class_name= (CONSTANT_Utf8_info) classFile.getConstant_pool() [this_class_cpInfo.getName_index().toInt()-1]; System.out.println(this_class_name); // super_class U2 super_class = classFile.getSuper_class(); CONSTANT_Class_info super_class_cpInfo = (CONSTANT_Class_info) classFile.getConstant_pool() [super_class.toInt() - 1]; CONSTANT_Utf8_info supor_class_name = (CONSTANT_Utf8_info) classFile.getConstant_pool() [super_class_cpInfo.getName_index().toInt()-1]; System.out.println(supor_class_name); } }
單元測試結果輸出如圖2.7所示。

圖2.7 this與super解析器單元測試
從輸出的結果可以看出,該class文件的類名為RecursionAlgorithmMain,父類的類名為Object。
注釋:
[1] 常量池索引都是從1開始的,0就表示不使用
- Android應用程序開發與典型案例
- C# 從入門到項目實踐(超值版)
- Java從入門到精通(第4版)
- Practical Game Design
- Mastering ServiceNow(Second Edition)
- Symfony2 Essentials
- SQL基礎教程(第2版)
- Delphi開發典型模塊大全(修訂版)
- 零基礎學C語言(第4版)
- Learning Unreal Engine Game Development
- Java從入門到精通(視頻實戰版)
- Developing Java Applications with Spring and Spring Boot
- 軟件測試(慕課版)
- Learning Shiny
- SQL Server 2014 Development Essentials