上QQ阅读APP看书,第一时间看更新
解析实现的接口
解析完this_class与super_class之后,就可以继续解析获取该class实现的接口总数以及该class实现的所有接口。接口解析器InterfacesHandler的实现如代码清单2-39所示。
代码清单2-39 InterfacesHandler类
public class InterfacesHandler implements BaseByteCodeHandler { @Override public int order() { return 5; } @Override public void read(ByteBuffer codeBuf, ClassFile classFile) throws Exception { // 接口总数interfaces_count classFile.setInterfaces_count(new U2(codeBuf.get(), codeBuf.get())); int interfaces_count = classFile.getInterfaces_count().toInt(); // 解析接口表 U2[] interfaces = new U2[interfaces_count]; classFile.setInterfaces(interfaces); for (int i = 0; i < interfaces_count; i++) { interfaces[i] = new U2(codeBuf.get(), codeBuf.get()); } } }
如代码清单2-39所示,read方法完成接口表的解析。在读取class文件字节缓存时,先顺序读取到interfaces_count,interfaces_count是类实现的接口总数。再根据interfaces_count创建接口表interfaces,接口表的数组长度等于interfaces_count。接口表中的每项都是一个常量索引,指向常量池表中CONSTANT_Class_info结构的常量。
将解析器注册到ClassFileAnalysiser,然后编写单元测试。由于接口表中的每项是指向常量池表中CONSTANT_Class_info结构的常量,因此,我们可以在单元测试中,根据CONSTANT_Class_info的name_index获取到对应的CONSTANT_Utf8_info常量,拿到接口的类型名称。单元测试如代码清单2-40所示。
代码清单2-40 接口解析器单元测试
public class InterfacesHandlerTest { @Test public void testInterfacesHandlerHandler() throws Exception { ByteBuffer codeBuf = ClassFileAnalysisMain.readFile("InterfacesHandler.class"); ClassFile classFile = ClassFileAnalysiser.analysis(codeBuf); System.out.println("接口总数:" + classFile.getInterfaces_count().toInt()); if (classFile.getInterfaces_count().toInt() == 0) { return; } U2[] interfaces = classFile.getInterfaces(); // 遍历接口表 for (U2 interfacesIndex : interfaces) { // 根据索引从常量池中取得一个CONSTANT_Class_info常量 CONSTANT_Class_info interfaces_class_info = (CONSTANT_Class_info) classFile.getConstant_pool() [interfacesIndex.toInt() - 1]; // 根据CONSTANT_Class_info的name_index从常量池取得一个 // CONSTANT_Utf8_info常量 CONSTANT_Utf8_info interfaces_class_name_info = (CONSTANT_Utf8_info) classFile.getConstant_pool() [interfaces_class_info.getName_index().toInt() - 1]; System.out.println(interfaces_class_name_info); } } }
单元测试结果输出如图2.8所示。
图2.8 接口解析器单元测试
从结果可以看出,该class文件实现的接口总数为1,实现的接口为BaseByteCodeHandler。