官术网_书友最值得收藏!

解析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就表示不使用

主站蜘蛛池模板: 盐池县| 吉安县| 武义县| 乐陵市| 嘉义市| 长春市| 博罗县| 南投县| 丰原市| 望都县| 海林市| 兴文县| 德清县| 临清市| 肇东市| 潞城市| 宜兰县| 凤翔县| 富民县| 腾冲县| 璧山县| 晋城| 建平县| 宣武区| 新丰县| 上栗县| 衡水市| 会东县| 如皋市| 庆阳市| 海南省| 临沭县| 时尚| 新津县| 浮山县| 即墨市| 昆山市| 石首市| 睢宁县| 鄂州市| 翁源县|