Java字节码(.class文件)的代码解析 (二)

2014-11-24 02:38:39 · 作者: · 浏览: 1
有getfield, putfield, getstatic, putstatic。

index = codes.readUnsignedShort();

builder.append("\t\t" + pool.getFieldRefInfo(index).toInstructionString(verbose) + "\n");

9. 非接口方法调用指令,也都是以两个字节的索引号作为操作数,指向常量池中的CONSTANT_Methodref_info类型结构,这些指令有invokespecial, invokevirtual, invokestatic。

index = codes.readUnsignedShort();

builder.append("\t\t" + pool.getMethodRefInfo(index).toInstructionString(verbose) + "\n");

10. 接口方法调用指令invokeinterface,它有四个字节的操作数,前两个字节为常量池的索引号,指向CONSTANT_InterfaceMethodref_info类型,第三个字节为count,表示参数的字节数,最后一个字节为0值。

index = codes.readUnsignedShort();

int nargs = codes.readUnsignedByte(); //Historical, redundant

builder.append("\t\t" + pool.getInterfaceMethodRefInfo(index).toInstructionString(verbose));

builder.append(" : " + nargs + "\n");

codes.readUnsignedByte(); //reserved should be zero

11. 基本类型的数组创建指令newarray,它的操作数为一个字节的类型标识。

String type = Constants.TYPE_NAMES[codes.readByte()];

builder.append(String.format("\t\t(%s)\n", type));

12. 多维数组的创建指令multianewarray,它有三个字节的操作数,前两个字节为索引号,指向CONSTANT_Class_info类型,表示数组的类型,最后一个字节指定数组的维度。

index = codes.readUnsignedShort();

int dimensions = codes.readUnsignedByte();

builder.append(String.format("\t\t%s (%d)\n", pool.getClassInfo(index).getName(), dimensions));

13. 常量入栈指令ldc,以一个字节的索引号作为参数,指向CONSTANT_Integer_info、CONSTANT_Float_info、CONSTANT_String_info、CONSTANT_Class_info类型,表示要入栈的常量值(int类型值、float类型值、String引用类型值或对象引用类型值)。

index = codes.readUnsignedByte();

builder.append("\t\t" + pool.getPoolItem(index).toInstructionString(verbose) + "\n");

14. 宽索引的常量入栈指令ldc_w,以两个字节的索引号作为参数,指向CONSTANT_Integer_info、CONSTANT_Float_info、CONSTANT_String_info、CONSTANT_Class_info类型,表示要入栈的常量值(int类型值、float类型值、String引用类型值或对象引用类型值)。

index = codes.readUnsignedShort();

builder.append("\t\t" + pool.getPoolItem(index).toInstructionString(verbose) + "\n");

15. 宽索引的常量入栈指令ldc2_w,以两个字节的索引号作为参数,指向CONSTANT_Long_info、CONSTANT_Double_info类型,表示要入栈的常量值(long类型值、double类型值)。

index = codes.readUnsignedShort();

builder.append("\t\t" + pool.getPoolItem(index).toInstructionString(verbose) + "\n");

16. bipush指令,以一个字节的常量作为操作数。

byte constByte = codes.readByte();

builder.append(“\t” + constByte);

17. sipush指令,以两个字节的常量作为操作数。

short constShort = codes.readShort();

builder.append(“\t” + constShort);

以上还有一些没有完成的代码,包括字段(方法)的签名和描述符没有解析,有一些解析的格式还需要调整等。不管怎么样,总体的结构就是这样了,其它的都是细节问题,这里不讨论了。

作者“上善若水”