JVM class文件结构


一、源代码

package com.tuling.smlz.jvm.classbyatecode;

/**
 * Created by smlz on 2019/11/5.
 */
public class TulingByteCode {

    private String userName;

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }
}

二、通过javap -verbose TulingByteCode .class反编译

//表示我们通过反编译的来源是哪个字节码文件
Classfile /D:/work_space/idea_space/spring-cloud-source/tuling-jvm/target/classes/com/tuling/smlz/jvm/classbyatecode/TulingByteCode.class
  //最后修改日期;文件大小
  Last modified 2019-11-5; size 629 bytes
  //文件的md5值
  MD5 checksum a0a9c001787f00738627278b0946a388
  //.class文件是通过哪个源文件编译过来的
  Compiled from "TulingByteCode.java"
  //字节码的详细信息
public class com.tuling.smlz.jvm.classbyatecode.TulingByteCode
  //jdk的次版本号
  minor version: 0
  //jdk的主版本号
  major version: 52
  //访问权限
  flags: ACC_PUBLIC, ACC_SUPER
  //常量池
Constant pool:
   #1 = Methodref          #4.#21         // java/lang/Object."<init>":()V
   #2 = Fieldref           #3.#22         // com/tuling/smlz/jvm/classbyatecode/TulingByteCode.userName:Ljava/lang/String;
   #3 = Class              #23            // com/tuling/smlz/jvm/classbyatecode/TulingByteCode
   #4 = Class              #24            // java/lang/Object
   #5 = Utf8               userName
   #6 = Utf8               Ljava/lang/String;
   #7 = Utf8               <init>
   #8 = Utf8               ()V
   #9 = Utf8               Code
  #10 = Utf8               LineNumberTable
  #11 = Utf8               LocalVariableTable
  #12 = Utf8               this
  #13 = Utf8               Lcom/tuling/smlz/jvm/classbyatecode/TulingByteCode;
  #14 = Utf8               getUserName
  #15 = Utf8               ()Ljava/lang/String;
  #16 = Utf8               setUserName
  #17 = Utf8               (Ljava/lang/String;)V
  #18 = Utf8               MethodParameters
  #19 = Utf8               SourceFile
  #20 = Utf8               TulingByteCode.java
  #21 = NameAndType        #7:#8          // "<init>":()V
  #22 = NameAndType        #5:#6          // userName:Ljava/lang/String;
  #23 = Utf8               com/tuling/smlz/jvm/classbyatecode/TulingByteCode
  #24 = Utf8               java/lang/Object
{ 
  //构造方法
  public com.tuling.smlz.jvm.classbyatecode.TulingByteCode();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: invokespecial #1                  // Method java/lang/Object."<init>":()V
         4: return
      LineNumberTable:
        line 6: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       5     0  this   Lcom/tuling/smlz/jvm/classbyatecode/TulingByteCode;
  //get方法
  public java.lang.String getUserName();
    descriptor: ()Ljava/lang/String;
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: getfield      #2                  // Field userName:Ljava/lang/String;
         4: areturn
      LineNumberTable:
        line 11: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       5     0  this   Lcom/tuling/smlz/jvm/classbyatecode/TulingByteCode;
  //set方法
  public void setUserName(java.lang.String);
    descriptor: (Ljava/lang/String;)V
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=2, args_size=2
         0: aload_0
         1: aload_1
         2: putfield      #2                  // Field userName:Ljava/lang/String;
         5: return
      LineNumberTable:
        line 15: 0
        line 16: 5
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       6     0  this   Lcom/tuling/smlz/jvm/classbyatecode/TulingByteCode;
            0       6     1 userName   Ljava/lang/String;
    MethodParameters:
      Name                           Flags
      userName
}
SourceFile: "TulingByteCode.java"

三、class文件通过16进制查看器打开如下

通过16进制查看器打开的文件结构是一个当个字节来显示,因为一个16进制数可以通过4位来表示,一个字节8位可以表示二个16进制数。
在这里插入图片描述
class文件结构图
在这里插入图片描述
Class文件结构参照表:

在这里插入图片描述
Class文件结构伪代码
在这里插入图片描述

3.1 魔数

我们通过javap -verbose来分析一个字节码的时候,将会分析字节码文件的魔数,主 次版本号,常量池,类信息,类的构造方法,类的中的方法信息,类变量与成员变量等信息。
魔数: 文件的开头的 四个字节 是固定 值位 0xCAFEBABE。
在这里插入图片描述

3.2 次版本号(minor version)

二个字节00 00 表示jdk的次版本号
在这里插入图片描述

3.3 主版本号(major version)

二个字节 00 34 表示为jdk的主版本号,34对于10进制为52,那么52代表的是1.8,51代表的是1.7 等等一直类推下去,二个字节00 00 表示jdk的次版本号。
在这里插入图片描述

3.4 常量池入口

占用二个字节,表示常量池中的个数=00 19 (25)-1=24个, 为啥需要-1,因为常量池中的第0个位置被jvm占用了表示为null 所以我们通过编译出来的常量池索引是从1开始的。

Constant pool:
   #1 = Methodref          #4.#21         // java/lang/Object."<init>":()V
   #2 = Fieldref           #3.#22         // com/tuling/smlz/jvm/classbyatecode/TulingByteCode.userName:Ljava/lang/String;
   #3 = Class              #23            // com/tuling/smlz/jvm/classbyatecode/TulingByteCode
   #4 = Class              #24            // java/lang/Object
   #5 = Utf8               userName
   #6 = Utf8               Ljava/lang/String;
   #7 = Utf8               <init>
   #8 = Utf8               ()V
   #9 = Utf8               Code
  #10 = Utf8               LineNumberTable
  #11 = Utf8               LocalVariableTable
  #12 = Utf8               this
  #13 = Utf8               Lcom/tuling/smlz/jvm/classbyatecode/TulingByteCode;
  #14 = Utf8               getUserName
  #15 = Utf8               ()Ljava/lang/String;
  #16 = Utf8               setUserName
  #17 = Utf8               (Ljava/lang/String;)V
  #18 = Utf8               MethodParameters
  #19 = Utf8               SourceFile
  #20 = Utf8               TulingByteCode.java
  #21 = NameAndType        #7:#8          // "<init>":()V
  #22 = NameAndType        #5:#6          // userName:Ljava/lang/String;
  #23 = Utf8               com/tuling/smlz/jvm/classbyatecode/TulingByteCode
  #24 = Utf8               java/lang/Object

3.4.1 常量池结构表

如图所示:u1,u2,u4,u8分别代表1个字节,2个字节,4个字节,8个字节的无符号数
在这里插入图片描述
在这里插入图片描述

3.4.2 常量池的作用

我们的常量池可以看作我们的java class类的一个资源仓库(比如Java类定的方法和变量信息),我们后面的方法 类的信息的描述信息都是通过索引去常量池中获取。
常量池中主要存放二种常量,一种是字面量 一种是符号引用
在这里插入图片描述
在这里插入图片描述

在JVM规范中,每个字段或者变量都有描述信息,描述信息的主要作用是 数据类型,方法参数列表,返回值类型等。
1)基本参数类型和void类型都是用一个大写的字符来表示,对象类型是通过一个大写L加全类名表示,这么做的好处就是在保证jvm能读懂class文件的情况下尽量的压缩class文件体积。
基本数据类型表示:

B---->byte
C---->char
D---->double 
F----->float
I------>int
J------>long
S------>short
Z------>boolean
V------->void

对象类型:

String------>Ljava/lang/String;(后面有一个分号)

数组类型:每一个唯独都是用一个前置 [ 来表示

 int[] ------>[ I, 
 String [][]------>[[Ljava.lang.String;

3.4.3 第1个常量池分析: 0A 00 04 00 15

0A:表示是常量池中的常量类型为方法引用
在这里插入图片描述
00 04:二个字节表示的是是方法所在类 指向常量池的索引位置为#4,然后我们发现#4的常量类型是Class,也是符号引用类型,指向常量池#24的位置,而#24是的常量池类型是字面量值为:java/lang/Object
00 15:二个字节表示是方法的描述符,指向常量池索引#21的位置,我们发现#21的常量类型是"NameAndType类型"属于引用类型,指向常量池的#7 #8位置
#7常量类型是UTF-8类型属于字面量值为: 为构造方法
#8常量也是UTF-8类型的字面量值为:()V
所以常量池中的第一个常量是:java/lang/Object.""😦)V(也就是调用Object类的构造方法,初始化所有类的根父类Object)
画图分析:
在这里插入图片描述
在这里插入图片描述

3.4.4 第2个常量池分析: 09 00 03 00 16

09表示的是我们的 CONSTANT_Methodref_info 字段类型的常量
在这里插入图片描述
00 03:表示的class_index 表示是常量池中第3个,为我们的class常量的索引位置
00 16:表示该字段的名称和类型 指向我们常量池中索引为22的位置
解释:03表示指向常量池第3个位置,我们发现第3个位子是Class类型的常量,03位置的常量池应用指向的是#23的位置,而我们的#23常量池类型是utf-8表示是字面量,值为:com/tuling/smlz/jvm/classbyatecode/TulingByteCode
#22为常量池类型的nameAndType类型,分别指向我们的常量池第#5(utf-8类型的常量)的位置表示我们的字段的名称userName,#6指向的是常量池第六个位置,类型是utf-8类型的值为:Ljava/lang/String;
所以常量池中的第二个常量是:com/tuling/smlz/jvm/classbyatecode/TulingByteCode.userName:Ljava/lang/String;
在这里插入图片描述
在这里插入图片描述

3.4.5 第3个常量池分析: 07 00 17

在这里插入图片描述
07:表示的是 class_info符号引用类型的常量
00 17:表示是指向常量池中索引为23的位置,#23的常量池类型是utf8字面量
所以常量池中的第3个常量是:com/tuling/smlz/jvm/classbyatecode/TulingByteCode
在这里插入图片描述
在这里插入图片描述

3.4.6 第4个常量池分析: 07 00 18

在这里插入图片描述
07:表示的是 class_info符号引用类型的常量
00 18:表示是指向常量池中索引为24的位置,#24的常量池类型是utf8字面量
所以常量池中的第3个常量是:java/lang/Object
在这里插入图片描述
在这里插入图片描述

3.4.7 第5个常量池分析: 01 00 08 75 73 65 72 4E 61 6D 65

在这里插入图片描述
01:tag位表示的是utf8类型的字面量常量
00 08:二个字节表示的是字面量常量的长度为8 、
75 73 65 72 4E 61 6D 65:转为字符串为userName
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.4.8 第6个常量池分析: 01 00 12 4C 6A 61 76 61 2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B

01:tag位表示的是utf8类型的字面量常量
00 12:二个字节表示的是字面量常量的长度为18 、
4C 6A 61 76 61 2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B: 转为字符串为 Ljava/lang/String;
在这里插入图片描述

3.4.9 第7个常量池分析: 01 00 06 3C 69 6E 69 74 3E

01:tag位表示的是utf8类型的字面量常量
00 06:二个字节表示的是字面量常量的长度为6
3C 69 6E 69 74 3E :转为字符串为
在这里插入图片描述

3.4.10 第8个常量池分析: 01 00 03 28 29 56

01:tag位表示的是utf8类型的字面量常量
00 03:二个字节表示的是字面量常量的长度为3
28 29 56:转为字符串为 ()V
在这里插入图片描述

3.4.11 第9个常量池分析: 01 00 04 43 6F 64 65

01:tag位表示的是utf8类型的字面量常量
00 04 :二个字节表示的是字面量常量的长度为4
43 6F 64 65 : 转为字符串为 Code
在这里插入图片描述

3.4.12 第10个常量池分析: 01 00 0F 4C 69 6E 65 4E 75 6D 62 65 72 54 61 62 6C 65

01:tag位表示的是utf8类型的字面量常量
00 0F:二个字节表示的是字面量常量的长度为15
4C 69 6E 65 4E 75 6D 62 65 72 54 61 62 6C 65 : 转为字符串为 LineNumberTable
表示这个是行号表
在这里插入图片描述

3.4.13 第11个常量池分析: 01 00 12 4C 6F 63 61 6C 56 61 72 69 61 62 6C 65 54 61 62 6C 65

01:tag位表示的是utf8类型的字面量常量
00 12:二个字节表示的是字面量常量的长度为18
4C 6F 63 61 6C 56 61 72 69 61 62 6C 65 54 61 62 6C 65 : 转为字符串为LocalVariableTable
表示这个是本地变量表
在这里插入图片描述

3.4.13 第12个常量池分析: 01 00 04 74 68 69 73

01:tag位表示的是utf8类型的字面量常量
00 14:二个字节表示的是字面量常量的长度为4
74 68 69 73: 转为字符串为this
在这里插入图片描述

3.4.14 第13个常量池分析: 01 00 33 4C 63 6F 6D 2F 74 75 6C 69 6E 67 2F 73 6D 6C 7A 2F 6A 76 6D 2F 63 6C 61 73 73 62 79 61 74 65 63 6F 64 65 2F 54 75 6C 69 6E 67 42 79 74 65 43 6F 64 65 3B

01:tag位表示的是utf8类型的字面量常量
00 33:二个字节表示的是字面量常量的长度为51
4C 63 6F 6D 2F 74 75 6C 69 6E 67 2F 73 6D 6C 7A 2F 6A 76 6D 2F 63 6C 61 73 73 62 79 61 74 65 63 6F 64 65 2F 54 75 6C 69 6E 67 42 79 74 65 43 6F 64 65 3B:表示字符串:Lcom/tuling/smlz/jvm/classbyatecode/TulingByteCode;
在这里插入图片描述

3.4.15 第14个常量池分析: 01 00 0B 67 65 74 55 73 65 72 4E 61 6D 65

01:tag位表示的是utf8类型的字面量常量
00 0B :二个字节表示的是字面量常量的长度为11
67 65 74 55 73 65 72 4E 61 6D 65 :表示的是字符串getUserName
在这里插入图片描述

3.4.16 第15个常量池分析: 01 00 14 28 29 4C 6A 61 76 61 2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B

01:tag位表示的是utf8类型的字面量常量
00 14: 二个字节表示的是字面量常量的长度为20
28 29 4C 6A 61 76 61 2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B :表示字符串 ()Ljava/lang/String;
在这里插入图片描述

3.4.17 第16个常量池分析: 01 00 0B 73 65 74 55 73 65 72 4E 61 6D 65

01:tag位表示的是utf8类型的字面量常量
00 0B :二个字节表示的是字面量常量的长度为11
73 65 74 55 73 65 72 4E 61 6D 65 :表示字符串 setUserName
在这里插入图片描述

3.4.18 第17个常量池分析: 01 00 15 28 4C 6A 61 76 61 2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29 56

01:tag位表示的是utf8类型的字面量常量
00 15: 二个字节表示的是字面量常量的长度为21
28 4C 6A 61 76 61 2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29 56:表示字符串 (Ljava/lang/String;)V
在这里插入图片描述

3.4.19 第18个常量池分析: 01 00 10 4D 65 74 68 6F 64 50 61 72 61 6D 65 74 65 72 73

01:tag位表示的是utf8类型的字面量常量
00 10 :二个字节表示的是字面量常量的长度为16
4D 65 74 68 6F 64 50 61 72 61 6D 65 74 65 72 73:表示字符串MethodParameters
在这里插入图片描述

3.4.20 第19个常量池分析: 01 00 0A 53 6F 75 72 63 65 46 69 6C 65

01:tag位表示的是utf8类型的字面量常量
00 0A: 二个字节表示的是字面量常量的长度为10
53 6F 75 72 63 65 46 69 6C 65:表示字符串SourceFile
在这里插入图片描述

3.4.21 第20个常量池分析: 01 00 13 54 75 6C 69 6E 67 42 79 74 65 43 6F 64 65 2E 6A 61 76 61

01:tag位表示的是utf8类型的字面量常量
00 13: 二个字节表示的是字面量常量的长度为19
54 75 6C 69 6E 67 42 79 74 65 43 6F 64 65 2E 6A 61 76 61:表示字符串TulingByteCode.java
在这里插入图片描述

3.4.22 第21个常量池分析:0C 00 07 00 08

在这里插入图片描述
0C:tag位表示的是符号引用 nameAndType_info类型的
00 07 :指向索引为7的常量池#7
00 08 :指向常量池8的位置#8
在这里插入图片描述

3.4.23 第22个常量池分析:0C 00 05 00 06

0C:tag位表示的是符号引用 nameAndType_info类型的
00 05 :指向索引为7的常量池#5
00 06: 指向常量池8的位置#6在这里插入图片描述

3.4.24 第23个常量池分析:01 00 31 63 6F 6D 2F 74 75 6C 69 6E 67 2F 73 6D 6C 7A 2F 6A 76 6D 2F 63 6C 61 73 73 62 79 61 74 65 63 6F 64 65 2F 54 75 6C 69 6E 67 42 79 74 65 43 6F 64 65

01:tag位表示的是utf8类型的字面量常量
00 31: 二个字节表示的是字面量常量的长度为49
63 6F 6D 2F 74 75 6C 69 6E 67 2F 73 6D 6C 7A 2F 6A 76 6D 2F 63 6C 61 73 73 62 79 61 74 65 63 6F 64 65 2F 54 75 6C 69 6E 67 42 79 74 65 43 6F 64 65:表示字符串com/tuling/smlz/jvm/classbyatecode/TulingByteCode
在这里插入图片描述

3.4.25 第24个常量池分析:01 00 10 6A 61 76 61 2F 6C 61 6E 67 2F 4F 62 6A 65 63 74

01:tag位表示的是utf8类型的字面量常量
00 10: 二个字节表示的是字面量常量的长度为16
6A 61 76 61 2F 6C 61 6E 67 2F 4F 62 6A 65 63 74:表示字符串java/lang/Object
在这里插入图片描述

四、Class文件结构访问标识符号解析 Access_flag 00 21

解析我们的class文件是类还是接口,是否定义为public的,是否是abstract,是否被final修饰。
00 21 :访问标志符号占用二个字节:
在这里插入图片描述
在这里插入图片描述
我们发现这个class文件的访问标识字节是0x0021,我们去查询手册中查询没有这个对应的?
原因:jvm规范并没有穷举出所以的类型 而是通过位运算的出来的.
0x0021 = 0x0020 位运算 0x0001 那么我们可以得出这个class的访问权限是ACC_PUBLICACC_SUPER
在这里插入图片描述

五、This class name的描述当前的所属类 00 03

00 03: this class name 占用二个字节表示索引,指向的是常量池中的第三个常量
在这里插入图片描述
根据第三部分常量池分析得出第三个常量分析得出如下
在这里插入图片描述
所以我们的this class name:表示当前类 com/tuling/smlz/jvm/classbyatecode/TulingByteCode

六、 super class name (当前class的父类名字)00 04

00 04: 同样占用二个字节 也是表示索引值,指向常量池中第四个常量
在这里插入图片描述
根据第三部分常量池的分析第四个常量池得出
在这里插入图片描述
所以我们的super class name表示的意思是: java/lang/Object

七、接口信息 00 02 00 08 00 09(**标注 我们的当前class没有实现接口为了演示效果我用的另外一个类演示) 这个类我们实现了二个接口 分别为ITulingIntf ITulingIntf

00 02 00 08 00 09 :这六个字节描述的信息是
在这里插入图片描述00 02:表示我们实现了几个接口 这里很明星我们是实现了二个接口
00 08(第一个接口): 表示的是接口的位于常量池中的索引.#8
在这里插入图片描述
所以00 08指向的接口是:com/tuling/smlz/jvm/classbyatecode/ITulingIntf
00 09(第二个接口):表示的是接口的位于常量池中的索引#9
在这里插入图片描述

八、字段表信息 00 01 00 02 00 05 00 06 00 00

作用:用于描述类和接口中声明的变量,包括类变量和实例变量
但是不包括方法的局部变量
00 01 00 02 00 05 00 06 00 00 :仅仅的接着接口信息后面的是字段描述
00 01 :二个字节表示的是field_info字段表的个数 这里很显然只有一个
在这里插入图片描述

8.1 字段结构体

在这里插入图片描述
00 02 00 05 00 06 00 00
00 02:表示访问修饰符号为ACC_PRIVATE,详见第四章
00 05: 表示的是字段的名称 指向的是常量池中第五个常量
在这里插入图片描述
00 06:是我们的字段的描述符: 指向的是常量池中第六个常量
在这里插入图片描述
00 00 :表示是属性表的个数 这里为0表示后面是没有属性表集合
通过jclasslib分析和我们自己分析的出来的结论一致
在这里插入图片描述

九、方法表信息分析 00 03 00 01 00 07 00 08 00 01

在这里插入图片描述
00 03 表示我们的方法的个数为三个
在这里插入图片描述
方法表结构:如下
在这里插入图片描述
第一个方法的前八个字节 00 01 00 07 00 08 00 01
在这里插入图片描述

9.1、acc_public

00 01:表示的是方法的修饰符 表示的是acc_public
在这里插入图片描述

9.2、name_index

00 07:表示的是方法的名称 表示指向常量池中第7个常量,表示方法的名称
表示构造方法
在这里插入图片描述

9.3、descriptior_index

00 08:方法的描述符号,表示指向常量池第八个常量 为()V 表示的是无参无返回值
在这里插入图片描述

9.4、attribute_count

00 01:表示有一个方法属性的个数

9.5、attribute_info

方法表中的属性表attribute_info结构图
在这里插入图片描述
在这里插入图片描述
00 09 00 00 00 2F

9.5.1、attribute_name_index

00 09:表示的是方法属性名称的索引指向常量池#9 表示是Code属性
在这里插入图片描述

9.5.2、attribute_length

00 00 00 2F : 标识的info的长度 长度值为47个字节 也就是说 会占据47个字节作为code的值
后续的47个字节是我们的Code属性的所占用的字节 (特别特别需要注意这47个字节从Code属性表中第三个开始也就是max_stack开始)
code_attribute属性表结构如下
在这里插入图片描述
在这里插入图片描述

9.5.2.1、max_stack

00 01 00 01 00 00 00 05 2A B7 00 01 B1 00 00 00 02 00 0A 00 00 00 06 00 01 00 00 00 06 00 0B 00 00 00 0C 00 01 00 00 00 05 00 0C 00 0D 00 00
**(max_stack)**表示的是我们最大操作数栈的深度为1
在这里插入图片描述

9.5.2.2、max_locals

00 01 00 01 00 00 00 05 2A B7 00 01 B1 00 00 00 02 00 0A 00 00 00 06 00 01 00 00 00 06 00 0B 00 00 00 0C 00 01 00 00 00 05 00 0C 00 0D 00 00
**(max_locals)**标识的是局部变量表变量的个数(这里只有一个this)
在这里插入图片描述

9.5.2.3、Code_lenth

00 01 00 01 00 00 00 05 2A B7 00 01 B1 00 00 00 02 00 0A 00 00 00 06 00 01 00 00 00 06 00 0B 00 00 00 0C 00 01 00 00 00 05 00 0C 00 0D 00 00
**(Code_lenth)**四个字节表示的是我们指令的长度为五

2A B7 00 01 B1 :字节码指令助记符号
0x2A:对应的字节码注记符是aload_0,作用就是把当前调用方法的栈帧中的局部变量表索引位置为0的局部变量推送到操作数栈的栈顶。
0xB7:表示是 invokespecial 调用父类的方法 那么后面需要接入二个字节表示调用哪个方法 所以 00 01 表示的是指向常量池中第一个位置为为如下结构
在这里插入图片描述
在这里插入图片描述
0xB1 :对应的字节码指令值retrun 表示retrun void from method;
在这里插入图片描述

9.5.2.4、exception_table_length

00 00 :异常信息表的个数为表示方法没有抛出异常
00 01 00 01 00 00 00 05 2A B7 00 01 B1 00 00 00 02 00 0A 00 00 00 06 00 01 00 00 00 06 00 0B 00 00 00 0C 00 01 00 00 00 05 00 0C 00 0D 00 00
在这里插入图片描述

9.5.2.5、attribute_count

00 02:表示Code_attribute结构中属性表的个数为2个
00 01 00 01 00 00 00 05 2A B7 00 01 B1 00 00 00 02 00 0A 00 00 00 06 00 01 00 00 00 06 00 0B 00 00 00 0C 00 01 00 00 00 05 00 0C 00 0D 00 00
在这里插入图片描述

9.5.2.6、attribute_info
9.5.2.6.1、 LineNumberTable

结构体为下图
在这里插入图片描述
00 01 00 01 00 00 00 05 2A B7 00 01 B1 00 00 00 02 00 0A 00 00 00 06 00 01 00 00 00 06 00 0B 00 00 00 0C 00 01 00 00 00 05 00 0C 00 0D 00 00
00 0A:这二个字节表示的是我们属性名称的索引attribute_name_index指向常量池中的00 0A #10个常量池
在这里插入图片描述
00 00 00 06:attribute_length:属性的长度占用四个字节: 表示后面 六个字节是我们属性的内容
00 01 00 01 00 00 00 05 2A B7 00 01 B1 00 00 00 02 00 0A 00 00 00 06 00 01 00 00 00 0**6 00 0B 00 00 00 0C 00 01 00 00 00 05 00 0C 00 0D 00 00
在这里插入图片描述
00 01:表示的是有几对指令码和源码映射关系 这里明显只有一对
00 01 00 01 00 00 00 05 2A B7 00 01 B1 00 00 00 02 00 0A 00 00 00 06 00 01 00 00 00 06 00 0B 00 00 00 0C 00 01 00 00 00 05 00 0C 00 0D 00 00
在这里插入图片描述
00 01 00 01 00 00 00 05 2A B7 00 01 B1 00 00 00 02 00 0A 00 00 00 06 00 01 00 00 00 06 00 0B 00 00 00 0C 00 01 00 00 00 05 00 0C 00 0D 00 00
00 00 00 06:这里表示 第一个指令码映射的是第六行源码

9.5.2.6.2、LocalVariableTable 本地方法变量表结构分析

在这里插入图片描述
00 01 00 01 00 00 00 05 2A B7 00 01 B1 00 00 00 02 00 0A 00 00 00 06 00 01 00 00 00 06 00 0B 00 00 00 0C 00 01 00 00 00 05 00 0C 00 0D 00 00
00 0B:本地变量表的名称的索引指向attribute_name_index的是常量池11的位置:
在这里插入图片描述
00 00 00 0C:本地变量表中属性的长度attribute_length:12长度
00 01 00 01 00 00 00 05 2A B7 00 01 B1 00 00 00 02 00 0A 00 00 00 06 00 01 00 00 00 06 00 0B 00 00 00 0C 00 01 00 00 00 05 00 0C 00 0D 00 00
00 01:本地变量表local_variable_table_length的个数
00 01 00 01 00 00 00 05 2A B7 00 01 B1 00 00 00 02 00 0A 00 00 00 06 00 01 00 00 00 06 00 0B 00 00 00 0C 00 01 00 00 00 05 00 0C 00 0D 00 00

local_vabiable_info的结构
在这里插入图片描述
00 00: start_pc:这个局部变量的生命周期开始的字节码偏移量 占用二个字节
00 01 00 01 00 00 00 05 2A B7 00 01 B1 00 00 00 02 00 0A 00 00 00 06 00 01 00 00 00 06 00 0B 00 00 00 0C 00 01 00 00 00 05 00 0C 00 0D 00 00
在这里插入图片描述
00 05:length:作用范围覆盖的长度 占用二个字节
00 01 00 01 00 00 00 05 2A B7 00 01 B1 00 00 00 02 00 0A 00 00 00 06 00 01 00 00 00 06 00 0B 00 00 00 0C 00 01 00 00 00 05 00 0C 00 0D 00 00
在这里插入图片描述
name_index:表示局部变量的名称 二个字节
00 0C:表示指向常量池12的位置
00 01 00 01 00 00 00 05 2A B7 00 01 B1 00 00 00 02 00 0A 00 00 00 06 00 01 00 00 00 06 00 0B 00 00 00 0C 00 01 00 00 00 05 00 0C 00 0D 00 00
在这里插入图片描述
在这里插入图片描述
desc_index:表示局部变量描述符索引 二个字节
00 0D表示指向常量池13的位置
00 01 00 01 00 00 00 05 2A B7 00 01 B1 00 00 00 02 00 0A 00 00 00 06 00 01 00 00 00 06 00 0B 00 00 00 0C 00 01 00 00 00 05 00 0C 00 0D 00 00
在这里插入图片描述
在这里插入图片描述

index:index是这个局部变量在栈帧局部变量表中Slot的位置。当这个变量数据类型是64位类型时(double和long),它占用的Slot为index和index+1两个
00 01 00 01 00 00 00 05 2A B7 00 01 B1 00 00 00 02 00 0A 00 00 00 06 00 01 00 00 00 06 00 0B 00 00 00 0C 00 01 00 00 00 05 00 0C 00 0D 00 00
在这里插入图片描述
第二和第三个方法同理不在赘述

十、对应的json文件

{
  "magic_num":"u4(CA FE BA BE)->desc:魔数" ,
  "minor_version":"u2(00 00)->desc:jdk的次版本号",
  "major_version":"u2(00 34->desc:52对应jdk主版本号1.8)",
  "constant_pool_count":"u2(00 19->desc:25-1=24个常量第0个被jvm占用表示null)",
  "constant_pool":{
    "CONSTANT_Methodref_info(第一个常量)":{
      "tag":"u1(0A)->desc:表示方法引用类型常量结构",
      "class_index":"u2(00 04)->desc:表示指向常量池中第四个常量,所属class",
      "name_and_type_index":"u2(00 15)->desc:指向常量池第21的位置,表示方法的描述符"
    },
    "CONSTANT_Fieldref_info(第二个常量)": {
      "tag":"u1(09)->desc:表示字段引用类型常量结构",
      "class_index":"u2(00 03)->desc:表示指向常量池中第3个常量,所属class",
      "name_and_type_index":"u2(00 16)->desc:指向常量池第22的位置,表示字段的描述符"
    },
    "CONSTANT_Class_info(第三个常量)": {
      "tag":"u1(07)->desc:表示class类型常量结构",
      "name_index":"u2(00 17)->desc:表示指向常量池中第23个常量,class的名称"
    },
    "CONSTANT_Class_info(第四个常量)": {
      "tag":"u1(07)->desc:表示class类型常量结构",
      "name_index":"u2(00 18)->desc:表示指向常量池中第24个常量,class的名称"
    },
    "CONSTANT_Utf8_info(第五个常量)": {
      "tag":"u1(01)->desc:表示utf-8类型常量结构",
      "length":"u2(00 08)->desc:紧接着后面8个字节表示的字面量",
      "byte[8]":"(75 73 65 72 4E 61 6D 65)->desc:userName "
    },
    "CONSTANT_Utf8_info(第六个常量)": {
      "tag":"u1(01)->desc:表示utf-8类型常量结构",
      "length":"u2(00 12)->desc:紧接着后面18个字节表示的字面量",
      "byte[18]":"(4C 6A 61 76 61 2F 6C 61 6E 67 2F 53 74 72 69 6E  67 3B )->desc:Ljava/lang/String;"
    },
    "CONSTANT_Utf8_info(第七个常量)": {
      "tag":"u1(01)->desc:表示utf-8类型常量结构",
      "length":"u2(00 06)->desc:紧接着后面6个字节表示的字面量",
      "byte[6]":"(3C 69 6E 69 74 3E)->desc:<init>"
    },
    "CONSTANT_Utf8_info(第八个常量)": {
      "tag":"u1(01)->desc:表示utf-8类型常量结构",
      "length":"u2(00 03)->desc:紧接着后面3个字节表示的字面量",
      "byte[6]":"(28 29  56 )->desc:()V"
    },
    "CONSTANT_Utf8_info(第九个常量)": {
      "tag":"u1(01)->desc:表示utf-8类型常量结构",
      "length":"u2(00 04)->desc:紧接着后面4个字节表示的字面量",
      "byte[4]":"(43 6F 64 65)->desc:Code"
    },
    "CONSTANT_Utf8_info(第十个常量)": {
      "tag":"u1(01)->desc:表示utf-8类型常量结构",
      "length":"u2(00 0F)->desc:紧接着后面15个字节表示的字面量",
      "byte[15]":"(4C 69 6E 65 4E  75 6D 62 65 72 54 61 62 6C 65 )-	 >desc:LineNumberTable"
    },
    "CONSTANT_Utf8_info(第十一个常量)": {
      "tag":"u1(01)->desc:表示utf-8类型常量结构",
      "length":"u2(00 12)->desc:紧接着后面18个字节表示的字面量",
      "byte[18]":"(4C 6F 63  61 6C 56 61 72 69 61 62 6C 65 54 61 62 6C 65)->desc:LocalVariableTable"
    },
    "CONSTANT_Utf8_info(第十二个常量)": {
      "tag":"u1(01)->desc:表示utf-8类型常量结构",
      "length":"u2(00 04)->desc:紧接着后面4个字节表示的字面量",
      "byte[4]":"(74 68 69 73)->desc:this"
    },
    "CONSTANT_Utf8_info(第十三个常量)": {
      "tag":"u1(01)->desc:表示utf-8类型常量结构",
      "length":"u2(00 33)->desc:紧接着后面51个字节表示的字面量",
      "byte[51]":"(4C 63 6F 6D 2F 74 75  6C 69 6E 67 2F 73 6D 6C 7A 2F 6A 76 6D 2F 63 6C  61 73 73 62 79 61 74 65 63 6F 64 65 2F 54 75 6C  69 6E 67 42 79 74 65 43 6F 64 65 3B )->desc:Lcom/tuling/smlz/jvm/classbyatecode/TulingByteCode;"
    },
    "CONSTANT_Utf8_info(第十四个常量)": {
      "tag":"u1(01)->desc:表示utf-8类型常量结构",
      "length":"u2(00 0B)->desc:紧接着后面11个字节表示的字面量",
      "byte[11]":"(67  65 74 55 73 65 72 4E 61 6D 65 )->desc:getUserName"
    },
    "CONSTANT_Utf8_info(第十五个常量)": {
      "tag":"u1(01)->desc:表示utf-8类型常量结构",
      "length":"u2(00 14)->desc:紧接着后面20个字节表示的字面量",
      "byte[20]":"(28 29 4C  6A 61 76 61 2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B )->desc:()Ljava/lang/String;"
    },
    "CONSTANT_Utf8_info(第十六个常量)": {
      "tag":"u1(01)->desc:表示utf-8类型常量结构",
      "length":"u2(00 0B)->desc:紧接着后面11个字节表示的字面量",
      "byte[11]":"(73 65 74 55 73 65 72 4E 61 6D 65)->desc:setUserName"
    },
    "CONSTANT_Utf8_info(第十七个常量)": {
      "tag":"u1(01)->desc:表示utf-8类型常量结构",
      "length":"u2(00 15)->desc:紧接着后面21个字节表示的字面量",
      "byte[21]":"(28 4C 6A 61 76 61 2F 6C 61 6E 67 2F 53 74  72 69 6E 67 3B 29 56 )->desc:(Ljava/lang/String;)V"
    },
    "CONSTANT_Utf8_info(第十八个常量)": {
      "tag":"u1(01)->desc:表示utf-8类型常量结构",
      "length":"u2(00 10)->desc:紧接着后面16个字节表示的字面量",
      "byte[16]":"(28 4C 6A 61 76 61 2F 6C 61 6E 67 2F 53 74  72 69 6E 67 3B 29 56 )->desc:MethodParameters"
    },
    "CONSTANT_Utf8_info(第十九个常量)": {
      "tag":"u1(01)->desc:表示utf-8类型常量结构",
      "length":"u2(00 0A)->desc:紧接着后面10个字节表示的字面量",
      "byte[10]":"(53 6F 75  72 63 65 46 69 6C 65  )->desc:SourceFile"
    },
    "CONSTANT_Utf8_info(第二十个常量)": {
      "tag":"u1(01)->desc:表示utf-8类型常量结构",
      "length":"u2(00 13)->desc:紧接着后面19个字节表示的字面量",
      "byte[19]":"(54 75 6C 69 6E 67  42 79 74 65 43 6F 64 65 2E 6A 61 76 61)->desc:TulingByteCode.java"
    },
    "CONSTANT_NameAndType_info(第二十一个常量)": {
      "tag":"u1(0C)->desc:表示NameAndType_类型常量结构",
      "name_index":"u2(00 07)->desc:指向常量池第七个-><init>",
      "descriptor_index":"u2(00 08)->指向常量池第八个->()V"
    },
    "CONSTANT_NameAndType_info(第二十二个常量)": {
      "tag":"u1(0C)->desc:表示NameAndType_类型常量结构",
      "name_index":"u2(00 05)->desc:指向常量池第五个->userName",
      "descriptor_index":"u2(00 06)->指向常量池第八个->Ljava/lang/String;"
    },
    "CONSTANT_Utf8_info(第二十三个常量)": {
      "tag":"u1(01)->desc:表示utf-8类型常量结构",
      "length":"u2(00 31)->desc:紧接着后面49个字节表示的字面量",
      "byte[49]":"(63 6F 6D 2F 74 75  6C 69 6E 67 2F 73 6D 6C 7A 2F 6A 76 6D 2F 63 6C  61 73 73 62 79 61 74 65 63 6F 64 65 2F 54 75 6C  69 6E 67 42 79 74 65 43 6F 64 65 )->desc:com/tuling/smlz/jvm/classbyatecode/TulingByteCode"
    },
    "CONSTANT_Utf8_info(第二十四个常量)": {
      "tag":"u1(01)->desc:表示utf-8类型常量结构",
      "length":"u2(00 10)->desc:紧接着后面49个字节表示的字面量",
      "byte[49]":"(6A 61  76 61 2F 6C 61 6E 67 2F 4F 62 6A 65 63 74 )->desc:java/lang/Object"
    }

  },
  "access_flag" :"u2(00 21)->desc:由0x0020(ACC_SUPER)和0x0001(ACC_PUBLIC) 位运算",
  "this_class_name":"u2(00 03)->desc:当前的class的名称 索引位置指向常量池#3,发现#3指向#23值,#23的值com/tuling/smlz/jvm/classbyatecode/TulingByteCode",
  "super_class_name":"u2(00 04)->desc:父类的class的 索引位置指向的常量池#4,发现#4指向到#24,值位:java/lang/Object",
  "interfaces_count":"u2(00 00)此时表示的接口的个数为0个,若接口的信息表为null",
  "interface[interfaces_count=0]":{},
  "fields_count":"u2(00 01)表示当前的class文件的字段的个数1个 ",
  "Field_info":{
    "Field_info[0]": {
      "access_flag": "u2(00 02)desc:->0x0002 ACC_PRIVATE",
      "name_index": "u2(00 05)->desc:->指向常量池#5 userName",
      "descciptor_index": "u2(00 06)->desc指向常量的第六个#6 Ljava/lang/String;",
      "attribute_count": "u2(00 00) 字段属性的个数为0那么没有字段属性",
      "attribute_info": {}
    }
  },
  "method_count":"u2(00 03)->desc:表示我们的方法的个数为三个",
  "method_infos": {
    "method_info[0]": {
      "access_flag": "u2(00 01)->desc:表示我们的方法访问权限为ACC_PUBLIC",
      "name_index": "u2(00 07)->desc:表示方法名称的索引指向常量池第七个位置#7 表示<init> 再编译时期生成的默认的构造函数",
      "descciptor_index": "u2(00 08)->desc:表示方法描述索引指向常量池#8 表示:()V 无参数,无返回值",
      "attribute_count": "u2(00 01)->desc:表示方法的属性个数",
      "attribute_infos": {
        "Code": {
          "attribute_name_index": "u2(00 09)->desc:我们属性的名称指向常量值索引的#9 位置 值为Code",
          "attribute_length": "u4(00 00 00 2F)-desc:表示我们的Code属性紧接着下来的47个字节是Code的内容",
          "max_stack": "u2(00 01)->desc:表示该方法的最大操作数栈的深度1",
          "max_locals": "u2(00 01)->desc:表示该方法的局部变量表的个数为1",
          "Code_length": "u4(00 00 00 05)->desc:指令码的长度为5",
          "Code[Code_length]": "2A B7 00 01 B1 其中0x002A->对应的字节码注记符是aload_0;0xB7->invokespecial;00 01表示表示是B7指令码操作的对象指向常量池中的#1(java/lang/Object.<init>:()V);B1表示调用方法返回void",
          "exception_table_length": "u2(00 00)->表示该方法不抛出异常,故exception_info没有异常信息",
          "exception_info": {},
          "attribute_count": "u2(00 02)->desc表示code属性表的属性个数为2",
          "attribute_info": {
            "LineNumberTable": {
              "attribute_name_index": "u2(00 0A)当前属性表名称的索引指向我们的常量池#10(LineNumberTable)",
              "attribute_length": "u4(00 00 00 06)当前属性表属性的字段占用6个字节是用来描述line_number_info",
              "mapping_count": "u2(00 01)->desc:该方法指向的指令码和源码映射的对数  表示一对",
              "line_number_infos": {
                "line_number_info[0]": {
                  "start_pc": "u2(00 00)->desc:表示指令码的行数",
                  "line_number": "u2(00 06)->desc:源码的行号"
                }
              }
            },
            "localVariableTable": {
              "attribute_name_index": "u2(00 0B)当前属性表名称的索引指向我们的常量池#10(localVariableTable)",
              "attribute_length": "u4(00  00 00 0C)当前属性表属性的字段占用12个字节用来描述local_variable_info",
              "local_variable_length": "u2(00 01)->desc:表示局部变量的个数1个",
              "local_variable_infos": {
                "local_variable_info[0]": {
                  "start_pc": "u2(00 00 )->desc:这个局部变量的生命周期开始的字节码偏移量",
                  "length:": "u2(00 05)->作用范围覆盖的长度为5",
                  "name_index": "u2(00 0c)->字段的名称索引指向常量池12的位置 this",
                  "desc_index": "u2(00 0D)局部变量的描述符号索引->指向#13的位置Lcom/tuling/smlz/jvm/classbyatecode/TulingByteCode;",
                  "index": "u2(00 00)->desc:index是这个局部变量在栈帧局部变量表中Slot的位置"
                }
              }
            }
          }
        }
      }
    },
    "method_info[1]": {
      "access_flag": "u2(00 01)->desc:表示我们的方法访问权限为ACC_PUBLIC",
      "name_index": "u2(00 0E)->desc:表示方法名称的索引指向常量池第14个位置#14 表示getUserName ",
      "descciptor_index": "u2(00 0F)->desc:表示方法描述索引指向常量池#5 表示:()Ljava/lang/String;无参数,返回值是String",
      "attribute_count": "u2(00 01)->desc:表示方法的属性个数",
      "attribute_info": {
        "Code": {
          "attribute_name_index": "u2(00 09)->desc:我们属性的名称指向常量值索引的#9 位置 值为Code",
          "attribute_length": "u4(00 00 00 2F)-desc:表示我们的Code属性紧接着下来的47个字节是Code的内容",
          "max_stack": "u2(00 01)->desc:表示该方法的最大操作数栈的深度1",
          "max_locals": "u2(00 01)->desc:表示该方法的局部变量表的个数为1",
          "Code_length": "u4(00 00 00 05)->desc:指令码的长度为5",
          "Code[Code_length]": "2A B4 00 02 B0  其中0x002A->对应的字节码注记符是aload_0;0xB4->getfield 获取指定类的实例域,并将其值压入栈顶;00 02表示表示是B4指令码操作的对象指向常量池中的#2(com/tuling/smlz/jvm/classbyatecode/TulingByteCode.userName:Ljava/lang/String;);B0表示为aretrun 返回  从当前方法返回对象引用",
          "exception_table_length": "u2(00 00)->表示该方法不抛出异常,故exception_info没有异常信息",
          "exception_info": {},
          "attribute_count": "u2(00 02)->desc表示code属性表的属性个数为2",
          "attribute_info": {
            "LineNumberTable": {
              "attribute_name_index": "u2(00 0A)当前属性表名称的索引指向我们的常量池#10(LineNumberTable)",
              "attribute_length": "u4(00 00 00 06)当前属性表属性的字段占用6个字节是用来描述line_number_info",
              "mapping_count": "u2(00 01)->desc:该方法指向的指令码和源码映射的对数  表示一对",
              "line_number_infos": {
                "line_number_info[0]": {
                  "start_pc": "u2(00 00)->desc:表示指令码的行数",
                  "line_number": "u2(00 0B)->desc:源码12行号"
                }
              },
              "localVariableTable": {
                "attribute_name_index": "u2(00 0B)当前属性表名称的索引指向我们的常量池#10(localVariableTable)",
                "attribute_length": "u4(00  00 00 0C)当前属性表属性的字段占用12个字节用来描述local_variable_info",
                "local_variable_length": "u2(00 01)->desc:表示局部变量的个数1",
                "local_vabiable_infos": {
                  "local_vabiable_info[0]": {
                    "start_pc": "u2(00 00 )->desc:这个局部变量的生命周期开始的字节码偏移量",
                    "length:": "u2(00 05)->作用范围覆盖的长度为5",
                    "name_index": "u2(00 0c)->字段的名称索引指向常量池12的位置 this",
                    "desc_index": "u2(00 0D)局部变量的描述符号索引->指向#13的位置Lcom/tuling/smlz/jvm/classbyatecode/TulingByteCode;",
                    "index": "u2(00 00)->desc:index是这个局部变量在栈帧局部变量表中Slot的位置"
                  }
                }
              }
            }
          }
        }
      }
    },
    "method_info[2]": {
      "access_flag": "u2(00 01)->desc:表示我们的方法访问权限为ACC_PUBLIC",
      "name_index": "u2(00 10)->desc:表示方法名称的索引指向常量池第16个位置#16 表示setUserName ",
      "descciptor_index": "u2(00 11)->desc:表示方法描述索引指向常量池#17 表示:(Ljava/lang/String;)V;String参数,返回void",
      "attribute_count": "u2(00 02)->desc:表示方法的属性个数2",
      "attribute_info": {
        "Code": {
          "attribute_name_index": "u2(00 09)->desc:我们属性的名称指向常量值索引的#9 位置 值为Code",
          "attribute_length": "u4(00 00 00 3E)-desc:表示我们的Code属性紧接着下来的62个字节是Code的内容",
          "max_stack": "u2(00 02)->desc:表示该方法的最大操作数栈的深度2",
          "max_locals": "u2(00 02)->desc:表示该方法的局部变量表的个数为2",
          "Code_length": "u4(00 00 00 06)->desc:指令码的长度为6",
          "Code[Code_length]": "2A 2B B5 00 02 B1    其中0x002A->对应的字节码注记符是aload_0;0x2B->aload_1 将第二个引用类型本地变量推送至栈顶;B5:putfield 用栈顶的值为指定的类的实例域赋值,00 02表示的是B5指令操作的对象,指向常量池中#2位置com/tuling/smlz/jvm/classbyatecode/TulingByteCode.userName:Ljava/lang/String; B1指令表示返回void",
          "exception_table_length": "u2(00 00)->表示该方法不抛出异常,故exception_info没有异常信息",
          "exception_info": {},
          "attribute_count": "u2(00 02)->desc表示code属性表的属性个数为2",
          "attribute_info": {
            "LineNumberTable": {
              "attribute_name_index": "u2(00 0A)当前属性表名称的索引指向我们的常量池#10(LineNumberTable)",
              "attribute_length": "u4(00 00 00 0A)当前属性表属性的字段占用10个字节是用来描述line_number_info",
              "mapping_count": "u2(00 02)->desc:该方法指向的指令码和源码映射的对数  表示二对",
              "line_number_infos": {
                "line_number_info[0]": {
                  "start_pc": "u2(00 00)->desc:表示指令码的行数",
                  "line_number": "u2(00 15)->desc:源码21行号"
                },
                "line_number_info[1]": {
                  "start_pc": "u2(00 05)->desc:表示指令码的5行",
                  "line_number": "u2(00 16)->desc:源码22行号"
                }
              }
            },
            "localVariableTable": {
              "attribute_name_index": "u2(00 0B)当前属性表名称的索引指向我们的常量池#10(localVariableTable)",
              "attribute_length": "u4(00 00 00 16)当前属性表属性的字段占用22个字节用来描述local_variable_info",
              "local_variable_length": "u2(00 02)->desc:表示局部变量的个数2",
              "local_variable_infos": {
                "local_variable_info[0]": {
                  "start_pc": "u2(00 00 )->desc:这个局部变量的生命周期开始的字节码偏移量",
                  "length:": "u2(00 06)->作用范围覆盖的长度为6",
                  "name_index": "u2(00 0c)->字段的名称索引指向常量池12的位置 this",
                  "desc_index": "u2(00 0D)局部变量的描述符号索引->指向#13的位置Lcom/tuling/smlz/jvm/classbyatecode/TulingByteCode;",
                  "index": "u2(00 00)->desc:index是这个局部变量在栈帧局部变量表中Slot的位置"
                },
                "local_variable_info[1]": {
                  "start_pc": "u2(00 00 )->desc:这个局部变量的生命周期开始的字节码偏移量",
                  "length:": "u2(00 06)->作用范围覆盖的长度为6",
                  "name_index": "u2(00 05)->字段的名称索引指向常量池5的位置 userName",
                  "desc_index": "u2(00 06)局部变量的描述符号索引->指向#6的位置 Ljava/lang/String;",
                  "index": "u2(00 01)->desc:index是这个局部变量在栈帧局部变量表中Slot的1位置"
                }
              }
            }
          }
        },
        "MethodParameters": {
          "attribute_name_index": "u2(00 12)表示该属性的名称指向常量池#18的位置:MethodParameters",
          "attribute_length": "u4(00 00 00 05 )->desc:属性的长度5",
          "parameter_count": "u1(01)->desc参数的个数1个",
          "parameter_name_index": "u2(00 05)->desc:指向第五个常量池的常量userName",
          "ACC_FLAG": "U2(00 00 )->desc:表示任何权限都可以访问"
        }
      }
    }
  },
  "attribute_count(class文件的属性)": "u2(00 01)只有一个属性",
  "attribute_info(class文件属性的结构)": {
      "attribute_name_index": "u2(00 13) 指向常量池中#19 值为 SourceFile",
      "attribute_length": "u4(00 00 00 02) 表示属性接下来的长度为2",
      "sourceFile_index": "u2(00 14) 表示源文件的索引指向常量池20的位置:TulingByteCode.java"
  }
}

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐