成员变量和成员方法的数据结构是一样的,所以可以使用相同的解析逻辑。首先解析出变量/方法的总数量,然后遍历并解析field_info或method_info对象的所有信息。
成员变量/成员方法解析代码片段:
// u2 fields_count;this.fieldsCount = dis.readUnsignedShort();// field_info fields[fields_count];for (int i = 0; i < this.fieldsCount; i++) {// field_info {// u2 access_flags;// u2 name_index;// u2 descriptor_index;// u2 attributes_count;// attribute_info attributes[attributes_count];// }this.fieldList.add(readFieldOrMethod());}/*** 读取成员变量或者方法的公用属性** @return 成员变量或方法属性信息* @throws IOException 读取异常*/private Map<String, Object> readFieldOrMethod() throws IOException {Map<String, Object> dataMap = new LinkedHashMap<>();// u2 access_flags;dataMap.put("access", dis.readUnsignedShort());// u2 name_index;dataMap.put("name", getConstantPoolValue(dis.readUnsignedShort()));// u2 descriptor_index;dataMap.put("desc", getConstantPoolValue(dis.readUnsignedShort()));// u2 attributes_count;int attributesCount = dis.readUnsignedShort();dataMap.put("attributesCount", attributesCount);// 读取成员变量属性信息dataMap.put("attributes", readAttributes(attributesCount));return dataMap;}
成员变量解析结果:
{"fieldsCount": 4,"fieldList": [{"access": 2,"name": "password","desc": "Ljava/lang/String;","attributesCount": 0,"attributes": { }},{"access": 2,"name": "id","desc": "J","attributesCount": 0,"attributes": { }},{"access": 26,"name": "serialVersionUID","desc": "J","attributesCount": 1,"attributes": {"attributeName": "ConstantValue","attributeLength": 2,"ConstantValue": {"constantValue": -7366591802115334000}}},{"access": 2,"name": "username","desc": "Ljava/lang/String;","attributesCount": 0,"attributes": { }}]}
成员方法解析结果(因结果过大,仅保留了一个getPassword方法):
{"methodsCount": 10,"methodList": [{"access": 1,"name": "getPassword","desc": "()Ljava/lang/String;","attributesCount": 1,"attributes": {"attributeName": "Code","attributeLength": 47,"Code": {"maxStack": 1,"maxLocals": 1,"codeLength": 5,"opcodes": ["aload_0","getfield #15 <com/anbai/sec/bytecode/TestHelloWorld.password>","areturn"],"exceptionTable": {"exceptionTableLength": 0,"exceptionTableList": [ ]},"attributeLength": 47,"attributes": {"attributeName": "LocalVariableTable","attributeLength": 12,"LineNumberTable": {"lineNumberTableLength": 1,"lineNumberTableList": [{"startPc": 0,"lineNumber": 49}]},"LocalVariableTable": {"localVariableTableLength": 1,"localVariableTableList": [{"startPc": 0,"length": 5,"name": "this","desc": "Lcom/anbai/sec/bytecode/TestHelloWorld;","index": 0}]}}}}}]}
