04-JVM字节码文件结构深度剖析

一、源代码

package com.tuling.jvm;

public class TulingByteCode {

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

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

在这里插入图片描述

//表示我们通过反编译的来源是哪个字节码文件
Classfile /F:/tulingxueyuan/jvm/out/production/jvm/com/tuling/jvm/TulingByteCode.class
  //最后修改日期;文件大小
  Last modified 2023-12-22; size 559 bytes
  //文件的md5值
  MD5 checksum 3863278550a593179635df261cce101c
  //.class文件是通过哪个源文件编译过来的
  Compiled from "TulingByteCode.java"
//字节码的详细信息
public class com.tuling.jvm.TulingByteCode
  //jdk的次版本号
  minor version: 0
  //jdk的主版本号
  major version: 52
  //访问权限
  flags: ACC_PUBLIC, ACC_SUPER
//常量池
Constant pool:
   #1 = Methodref          #4.#20         // java/lang/Object."<init>":()V
   #2 = Fieldref           #3.#21         // com/tuling/jvm/TulingByteCode.userName:Ljava/lang/String;
   #3 = Class              #22            // com/tuling/jvm/TulingByteCode
   #4 = Class              #23            // 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/jvm/TulingByteCode;
  #14 = Utf8               getUserName
  #15 = Utf8               ()Ljava/lang/String;
  #16 = Utf8               setUserName
  #17 = Utf8               (Ljava/lang/String;)V
  #18 = Utf8               SourceFile
  #19 = Utf8               TulingByteCode.java
  #20 = NameAndType        #7:#8          // "<init>":()V
  #21 = NameAndType        #5:#6          // userName:Ljava/lang/String;
  #22 = Utf8               com/tuling/jvm/TulingByteCode
  #23 = Utf8               java/lang/Object
{
  //构造方法
  public com.tuling.jvm.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/jvm/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 12: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       5     0  this   Lcom/tuling/jvm/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 16: 0
        line 17: 5
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       6     0  this   Lcom/tuling/jvm/TulingByteCode;
            0       6     1 userName   Ljava/lang/String;
}
SourceFile: "TulingByteCode.java"

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

通过16进制查看器【博主使用的EditPlus】打开的文件结构是一个当个字节来显示,因为一个16进制数可以通过4位来表示,一个字节8位可以表示二个16进制数。
在这里插入图片描述

class文件结构图

在这里插入图片描述

Class文件结构参照表

在这里插入图片描述

Class文件结构伪代码

在这里插入图片描述
我们通过javap -verbose来分析一个字节码的时候,将会分析字节码文件的魔数,主/次版本号,常量池,类信息,类的构造方法,类的中的方法信息,类变量与成员变量等信息。
3.1) 魔数 \color{red}魔数 魔数: 文件的开头的四个字节是固定值位 CAFEBABE
3.2) 次版本号 \color{red}次版本号 次版本号(minor version):二个字节00 00 表示jdk的次版本号
3.3) 主版本号 \color{red}主版本号 主版本号(major version):二个字节 00 34 表示为jdk的主版本号,34对于10进制为52
那么52代表的是1.8,51代表的是1.7 等等一直类推下去…
所以通过主次版本号来确定我们jdk的版本是1.8.0
在这里插入图片描述
3.4) 常量池入口 \color{red}常量池入口 常量池入口,占用二个字节,表示常量池中的个数=00 19 (24)-1=23个, 为啥需要-1,因为常量池中的第0个位置被我们的jvm占用了表示为null 所以我们通过编译出来的常量池索引是从1开始的。

3.4.1)常量池结构表如图所示
u1,u2,u4,u8分别代表1个字节,2个字节,4个字节,8个字节的无符号数
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
3.4.2)我们的常量池可以看作我们的java class类的一个资源仓库(比如Java类定的方法和变量信息),我们后面的方法 类的信息的描述信息都是通过索引去常量池中获取。
1)常量池中主要存放二种常量,一种是字面量 一种是符号引用
在这里插入图片描述
在这里插入图片描述

3.4.3)在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;

2)用描述符来描述方法的,先参数列表,后返回值的格式,参数列表按照严格的顺序放在()中
比如源码 String getUserInfoByIdAndName(int id,String name) 的方法描述符号
(I,Ljava/lang/String;)Ljava/lang/String;

第1个常量池分析: 0A 00 04 00 14
0A:表示是常量池中的常量类型为方法引用
在这里插入图片描述
00 04:二个字节表示的是是方法所在类 指向常量池的索引位置为#4,然后我们发现
#4的常量类型是Class,也是符号引用类型,指向常量池#23的位置,而#23是的常量池类型是字面量值为:java/lang/Object
00 14:二个字节表示是方法的描述符,指向常量池索引#20的位置,我们发现#20的常量类型是"NameAndType类型"属于引用类型,指向常量池的#7 #8位置
#7常量类型是UTF-8类型属于字面量值为: 为构造方法
#8常量也是UTF-8类型的字面量值为:()V
所以常量池中的第一个常量是:java/lang/Object.“”😦)V
画图分析:
在这里插入图片描述
在这里插入图片描述
第二个常量分析:09 00 03 00 15
09表示的是我们的 CONSTANT_Methodref_info 字段类型的常量
在这里插入图片描述
00 03:表示的class_index 表示是常量池中第三个 为我们的class常量的索引位置
00 15:表示该字段的名称和类型 指向我们常量池中索引为21的位置
解释:03表示指向常量池第三个位置,我们发现第三个位子是Class类型的常量,03位置的常量池应用指向的是#22的位置,而我们的#22常量池类型是utf-8表示是字面量
值为:com/tuling/smlz/jvm/classbyatecode/TulingByteCode
#21为常量池类型的nameAndType类型,分别指向我们的常量池第#5(utf-8类型的常量)的位置表示我们的字段的名称userName,#6指向的是常量池第六个位置,类型是utf-8类型的值为:Ljava/lang/String;
得出第二个常量为:com/tuling/smlz/jvm/classbyatecode/TulingByteCode.userName:Ljava/lang/String;
画图分析:
在这里插入图片描述
第三个常量分析: 07 00 16
在这里插入图片描述
第一个字节:07表示的是 class_info符号引用类型的常量
第二三个字节: 00 16表示是指向常量池中索引为22的位置,#22的常量池类型是utf8字面量
那么utf8_info的结构如下:
在这里插入图片描述
第#22的常量的结构是
其中 01表示utf8_info的常量类型
00 1D:表示后面跟着29个字节是字面量的值com/tuling/jvm/TulingByteCode
63 6F 6D 2F 74 75 6C 69 6E 67 2F 6A 76 6D 2F 54
75 6C 69 6E 67 42 79 74 65 43 6F 64 65
在这里插入图片描述
在这里插入图片描述
第四个常量分析: 07 00 17
在这里插入图片描述
第一个字节:07表示的是 class_info符号引用类型的常量
第二三个字节: 00 17表示是指向常量池中索引为23的位置,#23的常量池类型是utf8字面量
那么utf8_info的结构如下:
在这里插入图片描述
01 00 10 6A 61 76 61 2F 6C 61 6E 67 2F 4F 62 6A 65 63 74
其中 01表示utf8_info的常量类型
00 10:表示后面跟着16个字节是字面量的值
6A 61 76 61 2F 6C 61 6E 67 2F 4F 62 6A 65 63 74 字面量的值为:java/lang/Object
在这里插入图片描述
第五个常量: 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
在这里插入图片描述
在这里插入图片描述
第六个常量分析:
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;
在这里插入图片描述
在这里插入图片描述
第七个常量分析:01 00 06 3C 69 6E 69 74 3E
在这里插入图片描述
01:tag位表示的是utf8类型的字面量常量
00 06 二个字节表示的是字面量常量的长度为6
3C 69 6E 69 74 3E 转为字符串为
在这里插入图片描述
在这里插入图片描述
第八个常量分析:01 00 03 28 29 56
在这里插入图片描述
01:tag位表示的是utf8类型的字面量常量
00 03二个字节表示的是字面量常量的长度为3
28 29 56 转为字符串为 ()V
在这里插入图片描述
在这里插入图片描述
第九个常量分析:01 00 04 43 6F 64 65

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

第十个常量分析:
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
表示这个是行号表
在这里插入图片描述
在这里插入图片描述
第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
表示这个是本地变量表
在这里插入图片描述
在这里插入图片描述
第12个常量:
01 00 04 74 68 69 73
01:tag位表示的是utf8类型的字面量常量
00 14二个字节表示的是字面量常量的长度为4
74 68 69 73 转为字符串为this
在这里插入图片描述
在这里插入图片描述
第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
表示字符串: Lcom/tuling/smlz/jvm/classbyatecode/TulingByteCode;
在这里插入图片描述
在这里插入图片描述
第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
在这里插入图片描述
在这里插入图片描述
第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
接下来20个字节: 28 29 4C 6A 61 76 61 2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B 表示字符串
()Ljava/lang/String;
在这里插入图片描述
在这里插入图片描述
第16个常量池分析: 01 00 0B 73 65 74 55 73 65 72 4E 61 6D 65
01:tag位表示的是utf8类型的字面量常量
00 0B 二个字节表示的是字面量常量的长度为11
接下来11个字节: 73 65 74 55 73 65 72 4E 61 6D 65 表示字符串 setUserName
在这里插入图片描述
在这里插入图片描述
第17个常量池:
01 00 0A 53 6F 75 72 63 65 46 69 6C 65
01:tag位表示的是utf8类型的字面量常量
00 15 二个字节表示的是字面量常量的长度为21
接下来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
在这里插入图片描述
在这里插入图片描述
第18个常量: 01 00 0A 53 6F 75 72 63 65 46 69 6C 65
01:tag位表示的是utf8类型的字面量常量
00 0A 二个字节表示的是字面量常量的长度为10
接下来10个字节: 53 6F 75 72 63 65 46 69 6C 65 表示字符串SourceFile
在这里插入图片描述
在这里插入图片描述
第19个常量分析: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
接下来19个字节: 54 75 6C 69 6E 67 42 79 74 65 43 6F 64 65 2E 6A 61 76 61 表示字符串TulingByteCode.java
在这里插入图片描述
第20个常量池分析: 0C 00 07 00 08
在这里插入图片描述

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

第21个常量池:0C 00 05 00 06
在这里插入图片描述

0C:tag位表示的是符号引用 nameAndType_info类型的
00 05 指向索引为7的常量池#5
00 06 指向常量池8的位置#6
在这里插入图片描述
在这里插入图片描述
第22个常量池:
01 00 1D 63 6F 6D 2F 74 75 6C 69 6E 67 2F 6A 76 6D 2F 54 75 6C 69 6E 67
42 79 74 65 43 6F 64 65

01:tag位表示的是utf8类型的字面量常量
00 31 二个字节表示的是字面量常量的长度为49
接下来49个字节: 63 6F 6D 2F 74 75 6C 69 6E 67 2F 6A 76 6D 2F 54 75 6C 69 6E 67 42 79 74 65 43 6F 64 65 表示字符串com/tuling/jvm/TulingByteCode
在这里插入图片描述
在这里插入图片描述
第23个常量池: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
接下来16个字节: 6A 61 76 61 2F
6C 61 6E 67 2F 4F 62 6A 65 63 74 表示字符串java/lang/Object
在这里插入图片描述
在这里插入图片描述

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

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

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

在这里插入图片描述
所以我们的this class name:表示当前类 com.tuling.jvm.TulingByteCode

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

在这里插入图片描述
根据第三部分常量池的分析第四个常量池得出.
在这里插入图片描述

所以我们的super class name表示的意思是: java/lang/Object

七、接口信息(**标注 我们的当前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 二个字节表示的是field_info字段表的个数 这里很显然只有一个
在这里插入图片描述

字段结构体
在这里插入图片描述

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 01:表示的是方法的修饰符 表示的是acc_public
在这里插入图片描述

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

00 01表示有一个方法属性的个数
9.1)方法表中的属性表attribute_info结构图
在这里插入图片描述
00 09 00 00 00 2F
00 09:表示的是方法属性名称的索引指向常量池#9 表示是Code属性
在这里插入图片描述

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

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
(max_stack)表示的是我们最大操作数栈的深度为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
(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
(Code_lenth)四个字节表示的是我们指令的长度为五

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

0xB1 对应的字节码指令值retrun 表示retrun void from method;
在这里插入图片描述

异常信息表的个数为 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
在这里插入图片描述

表示Code_attribute结构中属性表的个数为00 02 表示为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
在这里插入图片描述

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
这二个字节表示的是我们属性名称的索引attribute_name_index指向常量池中的00 0A #10个常量池
在这里插入图片描述

attribute_length:属性的长度占用四个字节: 表示后面00 00 00 06 六个字节是我们属性的内容
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 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
这里表示 第一个指令码映射的是第六行源码

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
本地变量表的名称的索引指向attribute_name_index的是常量池11的位置:
在这里插入图片描述

本地变量表中属性的长度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
本地变量表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的结构
在这里插入图片描述

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
在这里插入图片描述

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
在这里插入图片描述

第二个方法的字节码
在这里插入图片描述

00 01 00 0E 00 0F 00 01 00 09 00 00 00 2F 00 01 00 01 00 00 00 05 2A B4 00 02 B0 00 00 00 02 00 0A 00 00 00 06 00 01 00 00 00 0B 00 0B 00 00 00 0C 00 01 00 00 00 05 00 0C 00 0D 00 00
1)方法访问标记符号:
0x0001我们根据访问权限修饰符号查询可得 访问权限是ACC_PUBLIC
00 01 00 0E 00 0F 00 01 00 09 00 00 00 2F 00 01 00 01 00 00 00 05 2A B4 00 02 B0 00 00 00 02 00 0A 00 00 00 06 00 01 00 00 00 0B 00 0B 00 00 00 0C 00 01 00 00 00 05 00 0C 00 0D 00 00
2)方法名称: 00 0E指向常量池中#14的位置
00 01 00 0E 00 0F 00 01 00 09 00 00 00 2F 00 01 00 01 00 00 00 05 2A B4 00 02 B0 00 00 00 02 00 0A 00 00 00 06 00 01 00 00 00 0B 00 0B 00 00 00 0C 00 01 00 00 00 05 00 0C 00 0D 00 00
在这里插入图片描述

3)方法描述符号:00 0F 指向我们的常量池#15的位置
00 01 00 0E 00 0F 00 01 00 09 00 00 00 2F 00 01 00 01 00 00 00 05 2A B4 00 02 B0 00 00 00 02 00 0A 00 00 00 06 00 01 00 00 00 0B 00 0B 00 00 00 0C 00 01 00 00 00 05 00 0C 00 0D 00 00
在这里插入图片描述

4)方法表属性个数 00 01 表示一个
00 01 00 0E 00 0F 00 01 00 09 00 00 00 2F 00 01 00 01 00 00 00 05 2A B4 00 02 B0 00 00 00 02 00 0A 00 00 00 06 00 01 00 00 00 0B 00 0B 00 00 00 0C 00 01 00 00 00 05 00 0C 00 0D 00 00
5)方法结构体中的attribute_info的结构体
在这里插入图片描述

5.1)attribute_info.attribute_name_index 表示的数属性名称索引 00 09指向常量池的位置: Code
00 01 00 0E 00 0F 00 01 00 09 00 00 00 2F 00 01 00 01 00 00 00 05 2A B4 00 02 B0 00 00 00 02 00 0A 00 00 00 06 00 01 00 00 00 0B 00 0B 00 00 00 0C 00 01 00 00 00 05 00 0C 00 0D 00 00
在这里插入图片描述

5.2)attribute_info.attribute_length表示的是我们属性的长度 00 00 00 2F
表示后面47个字节都是我们的Code_info结构体
00 01 00 0E 00 0F 00 01 00 09 00 00 00 2F 00 01 00 01 00 00 00 05 2A B4 00 02 B0 00 00 00 02 00 0A 00 00 00 06 00 01 00 00 00 0B 00 0B 00 00 00 0C 00 01 00 00 00 05 00 0C 00 0D 00 00
5.3)Code_info结构体如图所示
在这里插入图片描述

5.3.1)Code_info.max_stack方法操作数栈的深度
00 01表示方法操作数栈的深度为1
00 01 00 0E 00 0F 00 01 00 09 00 00 00 2F 00 01 00 01 00 00 00 05 2A B4 00 02 B0 00 00 00 02 00 0A 00 00 00 06 00 01 00 00 00 0B 00 0B 00 00 00 0C 00 01 00 00 00 05 00 0C 00 0D 00 00
在这里插入图片描述
5.3.2)Code_info.max_locals方法局部变量表的个数
00 01方法局部变量表的个数 1
00 01 00 0E 00 0F 00 01 00 09 00 00 00 2F 00 01 00 01 00 00 00 05 2A B4 00 02 B0 00 00 00 02 00 0A 00 00 00 06 00 01 00 00 00 0B 00 0B 00 00 00 0C 00 01 00 00 00 05 00 0C 00 0D 00 00
在这里插入图片描述

5.3.3)Code_info.code_length 指令码的长度 00 00 00 05 后面紧接着5个字节就是我们的具体指令码
00 01 00 0E 00 0F 00 01 00 09 00 00 00 2F 00 01 00 01 00 00 00 05 2A B4 00 02 B0 00 00 00 02 00 0A 00 00 00 06 00 01 00 00 00 0B 00 0B 00 00 00 0C 00 01 00 00 00 05 00 0C 00 0D 00 00

5.3.4)Code_info.code[code_length] 表示后面五个字节就是我们的指令码
00 01 00 0E 00 0F 00 01 00 09 00 00 00 2F 00 01 00 01 00 00 00 05 2A B4 00 02 B0 00 00 00 02 00 0A 00 00 00 06 00 01 00 00 00 0B 00 0B 00 00 00 0C 00 01 00 00 00 05 00 0C 00 0D 00 00
①:0x2A:对应的字节码注记符是aload_0,作用就是把当前调用方法的栈帧中的局部变量表索引位置为0的局部变量推送到操作数栈的栈顶.
②:0xb4 getfield 获取指定类的实例域,并将其值压入栈顶 后面是操作的字段
00 02表示常量池索引第二位置
B4 00 02 表示的意思就是把userName类型实例变量的引用压入方法的操作数栈
在这里插入图片描述
在这里插入图片描述

③:0xB4---->表示为aretrun 返回 从当前方法返回对象引用
5.3.5)Code_info.exception_table_length 异常表的个数: 00 00表示方法没有异常
00 01 00 0E 00 0F 00 01 00 09 00 00 00 2F 00 01 00 01 00 00 00 05 2A B4 00 02 B0 00 00 00 02 00 0A 00 00 00 06 00 01 00 00 00 0B 00 0B 00 00 00 0C 00 01 00 00 00 05 00 0C 00 0D 00 00
在这里插入图片描述

5.3.6)code_info.attribute_count 表示code_info属性attribute_info的个数 2个
00 01 00 0E 00 0F 00 01 00 09 00 00 00 2F 00 01 00 01 00 00 00 05 2A B4 00 02 B0 00 00 00 02 00 0A 00 00 00 06 00 01 00 00 00 0B 00 0B 00 00 00 0C 00 01 00 00 00 05 00 0C 00 0D 00 00
在这里插入图片描述

5.3.7)code_info.attribute_info[1]
在这里插入图片描述

①:00 0A表示为attribute_name_index指向常量池10的位置
在这里插入图片描述

00 01 00 0E 00 0F 00 01 00 09 00 00 00 2F 00 01 00 01 00 00 00 05 2A B4 00 02 B0 00 00 00 02 00 0A 00 00 00 06 00 01 00 00 00 0B 00 0B 00 00 00 0C 00 01 00 00 00 05 00 0C 00 0D 00 00
②: 00 00 00 06 表示的是attribute_length 表示长度,接着后面6个字节是我们的
line_number_info的结构体所再用的字节
00 01 00 0E 00 0F 00 01 00 09 00 00 00 2F 00 01 00 01 00 00 00 05 2A B4 00 02 B0 00 00 00 02 00 0A 00 00 00 06 00 01 00 00 00 0B 00 0B 00 00 00 0C 00 01 00 00 00 05 00 0C 00 0D 00 00

③:line_number_info结构体
00 01:表示字节码和源码映射的对数 01表示一对
00 00: 方法中的字节码的行号
00 0B: 源码中的行号 11行
00 01 00 0E 00 0F 00 01 00 09 00 00 00 2F 00 01 00 01 00 00 00 05 2A B4 00 02 B0 00 00 00 02 00 0A 00 00 00 06 00 01 00 00 00 0B 00 0B 00 00 00 0C 00 01 00 00 00 05 00 0C 00 0D 00 00
5.3.7)code_info.attribute_info[2]
在这里插入图片描述

00 01 00 0E 00 0F 00 01 00 09 00 00 00 2F 00 01 00 01 00 00 00 05 2A B4 00 02 B0 00 00 00 02 00 0A 00 00 00 06 00 01 00 00 00 0B 00 0B 00 00 00 0C 00 01 00 00 00 05 00 0C 00 0D 00 00
attribute_name_index 00 0B 表示的是指向我们的常量池中11的位置 为LocalVariableTable
在这里插入图片描述

attribute_length:00 00 00 0C 标识属性的长度为12,那么后面的12个字符就是我们的属性表的内容

local_varibale_info表的结构体
在这里插入图片描述

00 01 00 0E 00 0F 00 01 00 09 00 00 00 2F 00 01 00 01 00 00 00 05 2A B4 00 02 B0 00 00 00 02 00 0A 00 00 00 06 00 01 00 00 00 0B 00 0B 00 00 00 0C 00 01 00 00 00 05 00 0C 00 0D 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

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

第三个方法的字节码文件分析

00 01 00 10 00 11 00 02 00 09 00 00
00 3E 00 02 00 02 00 00 00 06 2A 2B B5 00 02 B1
00 00 00 02 00 0A 00 00 00 0A 00 02 00 00 00 15
00 05 00 16 00 0B 00 00 00 16 00 02 00 00 00 06
00 0C 00 0D 00 00 00 00 00 06 00 05 00 06 00 01
00 12 00 00 00 05 01 00 05 00 00
1)访问权限修饰符(这个权限修饰符为0x0001)
那么权限符是acc_public
00 01 00 10 00 11 00 02 00 09 00 00
00 3E 00 02 00 02 00 00 00 06 2A 2B B5 00 02 B1
00 00 00 02 00 0A 00 00 00 0A 00 02 00 00 00 15
00 05 00 16 00 0B 00 00 00 16 00 02 00 00 00 06
00 0C 00 0D 00 00 00 00 00 06 00 05 00 06 00 01
00 12 00 00 00 05 01 00 05 00 00
2)方法名称索引指向常量池中的#16
#16 = Utf8 setUserName
00 01 00 10 00 11 00 02 00 09 00 00
00 3E 00 02 00 02 00 00 00 06 2A 2B B5 00 02 B1
00 00 00 02 00 0A 00 00 00 0A 00 02 00 00 00 15
00 05 00 16 00 0B 00 00 00 16 00 02 00 00 00 06
00 0C 00 0D 00 00 00 00 00 06 00 05 00 06 00 01
00 12 00 00 00 05 01 00 05 00 00
3)方法描述符号索引 指向常量池中#17的位置
#17 = Utf8 (Ljava/lang/String;)V
00 01 00 10 00 11 00 02 00 09 00 00
00 3E 00 02 00 02 00 00 00 06 2A 2B B5 00 02 B1
00 00 00 02 00 0A 00 00 00 0A 00 02 00 00 00 15
00 05 00 16 00 0B 00 00 00 16 00 02 00 00 00 06
00 0C 00 0D 00 00 00 00 00 06 00 05 00 06 00 01
00 12 00 00 00 05 01 00 05 00 00
4)该方法属性表的个数 为2个
00 01 00 10 00 11 00 02 00 09 00 00
00 3E 00 02 00 02 00 00 00 06 2A 2B B5 00 02 B1
00 00 00 02 00 0A 00 00 00 0A 00 02 00 00 00 15
00 05 00 16 00 0B 00 00 00 16 00 02 00 00 00 06
00 0C 00 0D 00 00 00 00 00 06 00 05 00 06 00 01
00 12 00 00 00 05 01 00 05 00 00
4.1)第一个属性表Code属性表结构

①: 属性名称索引 指向常量池第九个位置
#9 = Utf8 Code
00 01 00 10 00 11 00 02 00 09 00 00
00 3E 00 02 00 02 00 00 00 06 2A 2B B5 00 02 B1
00 00 00 02 00 0A 00 00 00 0A 00 02 00 00 00 15
00 05 00 16 00 0B 00 00 00 16 00 02 00 00 00 06
00 0C 00 0D 00 00 00 00 00 06 00 05 00 06 00 01
00 12 00 00 00 05 01 00 05 00 00
②:属性长度 占用四个字节,四个字节计算出来的字节数字就是我们的Code属性内容
00 00 00 3E 转换成62个字节,那么我们后面的62个字节是我们的属性内容
00 01 00 10 00 11 00 02 00 09 00 00
00 3E 00 02 00 02 00 00 00 06 2A 2B B5 00 02 B1
00 00 00 02 00 0A 00 00 00 0A 00 02 00 00 00 15
00 05 00 16 00 0B 00 00 00 16 00 02 00 00 00 06
00 0C 00 0D 00 00 00 00 00 06 00 05 00 06 00 01
00 12 00 00 00 05 01 00 05 00 00
③:本方法最大操作数深度为2

00 01 00 10 00 11 00 02 00 09 00 00
00 3E 00 02 00 02 00 00 00 06 2A 2B B5 00 02 B1
00 00 00 02 00 0A 00 00 00 0A 00 02 00 00 00 15
00 05 00 16 00 0B 00 00 00 16 00 02 00 00 00 06
00 0C 00 0D 00 00 00 00 00 06 00 05 00 06 00 01
00 12 00 00 00 05 01 00 05 00 00
④:局部变量表的大小为2

00 01 00 10 00 11 00 02 00 09 00 00
00 3E 00 02 00 02 00 00 00 06 2A 2B B5 00 02 B1
00 00 00 02 00 0A 00 00 00 0A 00 02 00 00 00 15
00 05 00 16 00 0B 00 00 00 16 00 02 00 00 00 06
00 0C 00 0D 00 00 00 00 00 06 00 05 00 06 00 01
00 12 00 00 00 05 01 00 05 00 00
⑤:jvm指令码长度 ,占用四个字节 00 00 00 06
00 01 00 10 00 11 00 02 00 09 00 00
00 3E 00 02 00 02 00 00 00 06 2A 2B B5 00 02 B1
00 00 00 02 00 0A 00 00 00 0A 00 02 00 00 00 15
00 05 00 16 00 0B 00 00 00 16 00 02 00 00 00 06
00 0C 00 0D 00 00 00 00 00 06 00 05 00 06 00 01
00 12 00 00 00 05 01 00 05 00 00
⑥:jvm 指令解析 6个字节的指令码2A 2B B5 00 02 B1

00 01 00 10 00 11 00 02 00 09 00 00
00 3E 00 02 00 02 00 00 00 06 2A 2B B5 00 02 B1
00 00 00 02 00 0A 00 00 00 0A 00 02 00 00 00 15
00 05 00 16 00 0B 00 00 00 16 00 02 00 00 00 06
00 0C 00 0D 00 00 00 00 00 06 00 05 00 06 00 01
00 12 00 00 00 05 01 00 05 00 00
a) 0x2A->aload_0:表示把引用类型的压到我们操作数栈栈顶
b) 0x2B->aload_1:把我们第二个引用类型压入到操作数栈顶
c)0xB5->putFiled 把我们的栈顶的值赋值给实例变量
d)00 02: 表示putFiled的字端,表示操作的对象 指向我们的常量池#2的位置
e)0xB1:->从当前方法返回void
⑦:exception_table_length 异常表长度 为0,那么异常表个数为0

00 01 00 10 00 11 00 02 00 09 00 00
00 3E 00 02 00 02 00 00 00 06 2A 2B B5 00 02 B1
00 00 00 02 00 0A 00 00 00 0A 00 02 00 00 00 15
00 05 00 16 00 0B 00 00 00 16 00 02 00 00 00 06
00 0C 00 0D 00 00 00 00 00 06 00 05 00 06 00 01
00 12 00 00 00 05 01 00 05 00 00
⑧:Code属性表的attribute_info_count Code属性表的attribute属性个数

00 01 00 10 00 11 00 02 00 09 00 00
00 3E 00 02 00 02 00 00 00 06 2A 2B B5 00 02 B1
00 00 00 02 00 0A 00 00 00 0A 00 02 00 00 00 15
00 05 00 16 00 0B 00 00 00 16 00 02 00 00 00 06
00 0C 00 0D 00 00 00 00 00 06 00 05 00 06 00 01
00 12 00 00 00 05 01 00 05 00 00
A)Code_info的第一个属性表之lineNumberTable

attribute_name_index:0A 指向我们的常量池10的位置
#10 = Utf8 LineNumberTable
00 01 00 10 00 11 00 02 00 09 00 00
00 3E 00 02 00 02 00 00 00 06 2A 2B B5 00 02 B1
00 00 00 02 00 0A 00 00 00 0A 00 02 00 00 00 15
00 05 00 16 00 0B 00 00 00 16 00 02 00 00 00 06
00 0C 00 0D 00 00 00 00 00 06 00 05 00 06 00 01
00 12 00 00 00 05 01 00 05 00 00
attribute_length:占用四个字节 00 00 00 0A(10字节)
表示后面字节是我们的具体的属性

00 01 00 10 00 11 00 02 00 09 00 00
00 3E 00 02 00 02 00 00 00 06 2A 2B B5 00 02 B1
00 00 00 02 00 0A 00 00 00 0A 00 02 00 00 00 15
00 05 00 16 00 0B 00 00 00 16 00 02 00 00 00 06
00 0C 00 0D 00 00 00 00 00 06 00 05 00 06 00 01
00 12 00 00 00 05 01 00 05 00 00
line_number_table_length:占用二个字节 表示2对映射
00 01 00 10 00 11 00 02 00 09 00 00
00 3E 00 02 00 02 00 00 00 06 2A 2B B5 00 02 B1
00 00 00 02 00 0A 00 00 00 0A 00 02 00 00 00 15
00 05 00 16 00 0B 00 00 00 16 00 02 00 00 00 06
00 0C 00 0D 00 00 00 00 00 06 00 05 00 06 00 01
00 12 00 00 00 05 01 00 05 00 00
line_number_info存在二对映射

00 01 00 10 00 11 00 02 00 09 00 00
00 3E 00 02 00 02 00 00 00 06 2A 2B B5 00 02 B1
00 00 00 02 00 0A 00 00 00 0A 00 02 00 00 00 15
00 05 00 16 00 0B 00 00 00 16 00 02 00 00 00 06
00 0C 00 0D 00 00 00 00 00 06 00 05 00 06 00 01
00 12 00 00 00 05 01 00 05 00 00
指令码 00 映射源码 00 15(21)行
指令码05 映射源码00 16(22行)

B)Code_info的第二个属性表之LocalVariableTable

00 01 00 10 00 11 00 02 00 09 00 00
00 3E 00 02 00 02 00 00 00 06 2A 2B B5 00 02 B1
00 00 00 02 00 0A 00 00 00 0A 00 02 00 00 00 15
00 05 00 16 00 0B 00 00 00 16 00 02 00 00 00 06
00 0C 00 0D 00 00 00 00 00 06 00 05 00 06 00 01
00 12 00 00 00 05 01 00 05 00 00
attribute_name_index 00 0B指向我们的常量池11的位置
#11 = Utf8 LocalVariableTable

attribute_length表示属性的长度,后面的22个字节都是我们的属性类容
00 01 00 10 00 11 00 02 00 09 00 00
00 3E 00 02 00 02 00 00 00 06 2A 2B B5 00 02 B1
00 00 00 02 00 0A 00 00 00 0A 00 02 00 00 00 15
00 05 00 16 00 0B 00 00 00 16 00 02 00 00 00 06
00 0C 00 0D 00 00 00 00 00 06 00 05 00 06 00 01
00 12 00 00 00 05 01 00 05 00 00

local_variable_table_length 00 02(表示有二个本地变量表)
00 01 00 10 00 11 00 02 00 09 00 00
00 3E 00 02 00 02 00 00 00 06 2A 2B B5 00 02 B1
00 00 00 02 00 0A 00 00 00 0A 00 02 00 00 00 15
00 05 00 16 00 0B 00 00 00 16 00 02 00 00 00 06
00 0C 00 0D 00 00 00 00 00 06 00 05 00 06 00 01
00 12 00 00 00 05 01 00 05 00 00

Local_variale_info的变量表结构

第一个变量表:
00 01 00 10 00 11 00 02 00 09 00 00
00 3E 00 02 00 02 00 00 00 06 2A 2B B5 00 02 B1
00 00 00 02 00 0A 00 00 00 0A 00 02 00 00 00 15
00 05 00 16 00 0B 00 00 00 16 00 02 00 00 00 06
00 0C 00 0D 00 00 00 00 00 06 00 05 00 06 00 01
00 12 00 00 00 05 01 00 05 00 00
“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的位置”

第二个变量表:
00 01 00 10 00 11 00 02 00 09 00 00
00 3E 00 02 00 02 00 00 00 06 2A 2B B5 00 02 B1
00 00 00 02 00 0A 00 00 00 0A 00 02 00 00 00 15
00 05 00 16 00 0B 00 00 00 16 00 02 00 00 00 06
00 0C 00 0D 00 00 00 00 00 06 00 05 00 06 00 01
00 12 00 00 00 05 01 00 05 00 00
“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位置”

B)Code_info的第二个属性表之MethodParameters方法参数属性表
00 01 00 10 00 11 00 02 00 09 00 00
00 3E 00 02 00 02 00 00 00 06 2A 2B B5 00 02 B1
00 00 00 02 00 0A 00 00 00 0A 00 02 00 00 00 15
00 05 00 16 00 0B 00 00 00 16 00 02 00 00 00 06
00 0C 00 0D 00 00 00 00 00 06 00 05 00 06 00 01
00 12 00 00 00 05 01 00 05 00 00
结构体:
{
“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:表示任何权限都可以访问”
}

最后一部分:class文件的属性
00 01 00 13 00 00 00 02 00 14
“attribute_count(class文件的属性)”:“u2(00 01)只有一个属性”
属性结构体:
{
“attribute_name_index”:“u2(00 13) 指向常量池中#19 值为 SourceFile”,
“attribute_length”:“u4(00 00 00 02) 表示属性接下来的长度为2”,
“sourceFile_index”:“u2(00 14) 表示源文件的索引指向常量池20的位置:TulingByteCode.java”
}

引用文章

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/268321.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Springboot+vue的交通管理在线服务系统(有报告)。Javaee项目,springboot vue前后端分离项目

演示视频&#xff1a; Springbootvue的交通管理在线服务系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot vue前后端分离项目 项目介绍&#xff1a; 本文设计了一个基于Springbootvue的前后端分离的交通管理在线服务系统&#xff0c;采用M&#xff08;m…

详解KMP算法

KMP算法应该是每一本《数据结构》书都会讲的&#xff0c;算是知名度最高的算法之一了&#xff0c;但很可惜&#xff0c;我大二那年压根就没看懂过~~~ 之后也在很多地方也都经常看到讲解KMP算法的文章&#xff0c;看久了好像也知道是怎么一回事&#xff0c;但总感觉有些地方自己…

相机内参标定理论篇------张正友标定法

一、为什么做相机标定&#xff1f; 标定是为了得到相机坐标系下的点和图像像素点的映射关系&#xff0c;为摄影几何、计算机视觉等应用做准备。 二、为什么需要张正友标定法&#xff1f; 张正友标定法使手工标定相机成为可能&#xff0c;使相机标定不再需要精密的设备帮助。…

63. 不同路径 II 23.12.21(二)

一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish”&#xff09;。 现在考虑网格中有障碍物。那么从左上角到右下角…

智能优化算法应用:基于白鲸算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于白鲸算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于白鲸算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.白鲸算法4.实验参数设定5.算法结果6.参考文献7.MA…

ansible(二)

模块七&#xff1a; hostname模块&#xff0c;修改主机名 模块八&#xff1a; copy模块&#xff1a;用于复制指定主机的文件到远程主机的模块&#xff08;必须要用绝对路径&#xff09; 常用的参数&#xff1a; Dest:指出要复制的文件在哪&#xff08;去哪&#xff09;&am…

外星人Alienware Area-51 R2原厂Win10预装系统

大三角外星人Area 15 R2原装出厂WINDOWS10系统 链接&#xff1a;https://pan.baidu.com/s/1JwDuHx1j7fRABtIpLmKW_g?pwdq4pd 提取码&#xff1a;q4pd 原厂系统自带所有驱动、外星人出厂主题壁纸、专属LOGO标志、Office办公软件、MyAlienware、外星人控制中心等预装程序 文…

[论文分享]TimeDRL:多元时间序列的解纠缠表示学习

论文题目&#xff1a;TimeDRL: Disentangled Representation Learning for Multivariate Time-Series 论文地址&#xff1a;https://arxiv.org/abs/2312.04142 代码地址&#xff1a;暂无 关键要点&#xff1a;多元时间序列&#xff0c;自监督表征学习&#xff0c;分类和预测 摘…

【杂】如何修复视频--> Wondershare Repairit

近日换宿舍&#xff0c;从一个校区搬到另一个校区&#xff0c;突发奇想决定用相机录一点视频~ 浅浅尝试一下录vlog才发现做短视频也并非想象中那般容易&#xff0c;尤其是构思内容和文案&#xff0c;并且实施起来也会有很多问题&#xff0c;比如手拿着相机录真的很抖o((⊙﹏⊙)…

车手互联是不是杀手锏,来听听一家头部手机厂的座舱方法论

作者 |Amy 编辑 |德新 十年前&#xff0c; 苹果CarPlay和谷歌Android Auto相继推出&#xff0c;手机与车机两个此前貌似无关的品类&#xff0c;从此开始产生交集。 科技巨头看好车机的硬生态&#xff0c;汽车大鳄们则垂涎于科技圈的软实力。 CarPlay和Android Auto的出现&am…

《操作系统A》期末考试复习题——大题51-62(手写笔记)

51、如果限制为两道的多道程序系统中&#xff0c;有4个作业进入系统&#xff0c;其进入系统时刻、估计运行时间为下图所示。系统采用SJF作业调度算法&#xff0c;采用SRTF进程调度算法。作业进入系统时刻、估计运行时间如下&#xff1a; 作业 进入系统时刻 估计运行时间/min …

PHP代码审计之反序列化攻击链CVE-2019-6340漏洞研究

关键词 php 反序列化 cms Drupal CVE-2019-6340 DrupalKernel 前言 简简单单介绍下php的反序列化漏洞 php反序列化漏洞简单示例 来看一段简单的php反序列化示例 <?phpclass pingTest {public $ipAddress "127.0.0.1";public $isValid False;public $output…

1979 年至今的每日地面气象数据AgERA5 (ECMWF) 数据集

AgERA5 (ECMWF) 数据集 1979 年至今的每日地面气象数据&#xff0c;作为农业和农业生态研究的输入。该数据集基于地表每小时 ECMWF ERA5 数据&#xff0c;称为 AgERA5。原始ERA5数据的采集和预处理是一项复杂且专业的工作。通过提供 AgERA5 数据集&#xff0c;用户可以从这项工…

基于Java (spring-boot)的仓库管理系统

一、项目介绍 本系统的使用者一共有系统管理员、仓库管理员和普通用户这3种角色: 1.系统管理员&#xff1a;通过登录系统后&#xff0c;可以进行管理员和用户信息的管理、仓库和物品分类的管理&#xff0c;以及操作日志的查询&#xff0c;具有全面的系统管理权限。 2.仓库管理…

CPP虚析构函数

#include<iostream> using namespace std;class base {public:base(){};virtual ~base(){}; };// 在类声明中声明纯虚析构函数 //base::~base() {}class father: public base {public:~father(){cout << "father" << endl;} };int main() {base* a…

沉浸式go-cache源码阅读!

大家好&#xff0c;我是豆小匠。 这期来阅读go-cache的源码&#xff0c;了解本地缓存的实现方式&#xff0c;同时掌握一些阅读源码的技巧~ 1. 源码获取 git clone https://github.com/patrickmn/go-cache.git用Goland打开可以看到真正实现功能的也就两个go文件&#xff0c;ca…

低代码平台表单引擎设计器

目录 一、前言 二、JNPF表单设计组成 功能一览&#xff1a; 三、低代码哲学 四、结语 一、前言 无论是构建SaaS产品&#xff0c;还是开发内部工具&#xff0c;甚至是服务于消费者的C端产品&#xff0c;表单始终是不可或缺的一环。作为支持用户提交信息的核心组件&#xff…

数学建模之聚类模型详解

聚类模型 引言 “物以类聚&#xff0c;人以群分”&#xff0c;所谓的聚类&#xff0c;就是将样本划分为由类似的对象组成的多个类的过程。聚类后&#xff0c;我们可以更加准确的在每个类中单独使用统计模型进行估计、分析或预测&#xff1b;也可以探究不同类之间的相关性和主…

员工考核UI网页界面(PS大屏文件资料)

现分享人员管理可视化数据统计网页UI、员工考核数据可视化UI网页界面模版的UI源文件&#xff0c;供UI设计师们快速获取PSD源文件完成工作。 若需更多 大屏组件&#xff0c;请移步小7的另一篇文章&#xff1a;数据可视化大屏组件&#xff0c;大屏PSD设计源文件(大屏UI设计规范)…

C++ 之LeetCode刷题记录(二)

&#x1f604;&#x1f60a;&#x1f606;&#x1f603;&#x1f604;&#x1f60a;&#x1f606;&#x1f603; 从今天开始cpp刷题之旅&#xff0c;多学多练&#xff0c;尽力而为。 先易后难&#xff0c;先刷简单的。 9、回文数 给你一个整数 x &#xff0c;如果 x 是一个…
最新文章