Methods
方法包括两部分,第一个是methods_count(方法个数),第二部分methods(方法名) 。
当前这个类对应的十六进制:00 03转换为十进制值为3,说明这个类内部有三个方法 。
三个方法为:
setA、getA,以及默认无参的构造方法 。
方法表结构:

文章插图
具体含义类似于上述的字段表结构 。
access_flags 对应的十六进制:00 01 在标志结构表中查找为ACC_PUBLIC 。
name_index名称索引对应十六进制 00 07 descriptor_index描述符索引对应十六进制 00 08
分别转换为十进制为 7 和 8,在常量池中查找结果:
#7 = Utf8 <init> // 表示这个类的构造方法#8 = Utf8 V // 表示不接收任何参数的不返回结果的描述符attributes_count对应十六进制:00 01,其个数为1,表示会有一个附加属性 。也说明了有一个attributes 。方法的属性结构构成:
方法中的每一个属性都是一个atrribute_info结构 。
atrribute_info {u2 atrribute_name_index;u4 attribute_length;u1 info[atrribute_length];}attribute_name_index对应十六进制为 00 09,在常量池结构表中查找结果:#9 = Utf8 Code从字节码中每一个方法中都能体现出来,比如默认构造方法:public com.dskj.jvm.bytecode.MyTest1;descriptor: Vflags: ACC_PUBLICCode:...然后根据 atrribute_length 对应十六进制为 00 00 00 38 转换为十进制为3 * 16的一次方 + 8 = 56说明在这个十六进制后面找到56个字节作为Code这个属性的具体的值 。
方法表结构:
前三个字段和field_info一样 。
method_info {u2 access_flags;u2 name_index;u2 descriptor_index;u2 attributes_count;attribute_info attributes[attributes_count]}方法的属性结构:- JVM预定了部分atrribute,但是编译器自己也可以实现自己的atrribute写入class文件里,供运行时使用 。
- 不同的attribute通过attribute_name_index来区分 。

文章插图
Code attribute的作用是保存该方法的结构,如所对应的字节码 。
- attribute_length表示attribute所包含的字节数,不包含atrribute_name_index和attribute_length字段 。
- max_stack表示这个方法运行的任何时刻所能达到的操作数栈的最大深度 。// 00 02
- max_locals表示方法执行期间创建的局部变量的数目,包含用来表示传入的参数的局部变量的 。// 00 01
- code_length表示该方法所包含的字节码的字节数以及具体的指令码 。也即助记符 。// 00 00 00 0A 转换为十进制值为10,即跟着后面的10个字节 2A B7 00 01 2A 04 B5 00 02 B1 这些是字节码具体指令,对应到构造方法的字节码:
我们通过jclasslib工具(字节码查看工具,支持IDEA插件形式安装)查看时,点击助记符的链接会跳到Oracle官网可查看具体详细解释 。第一个助记符: 0: aload_0 打开链接可以看到:
链接地址:
https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.aload_n
具体解释内容所示:
aload_<n>OperationLoad reference from local variableFormataload_<n>Formsaload_0 = 42 (0x2a) // 通过这里就能直接看到 aload_0 对应的十进制是42,转换为十六进制就是 0x2a,对应字节码文件中的 2Aaload_1 = 43 (0x2b)aload_2 = 44 (0x2c)aload_3 = 45 (0x2d)DescriptionThe <n> must be an index into the local variable array of the current frame (§2.6). The local variable at <n> must contain a reference. The objectref in the local variable at <n> is pushed onto the operand stack.这个<n>必须是一个到当前栈帧局部变量数组的一个索引,位于<n>位置上的局部变量会包含一个引用,位于<n>位置上的局部变量的这个引用会被推送到栈顶(准备进行操作) 。第二个助记符:1: invokespecial #1 // Method java/lang/Object."<init>":V连接地址:https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.invokespecialinvokespecialOperationInvoke instance method; special handling for superclass, private, and instance initialization method invocationsFormatinvokespecialindexbyte1indexbyte2Formsinvokespecial = 183 (0xb7)Operand Stack..., objectref, [arg1, [arg2 ...]] →...