程序员社区

【Java 虚拟机原理】Class 字节码二进制文件分析 二 ( 常量池位置 | 常量池结构 | tag | info[] | 完整分析字节码文件中的常量池二进制数据 )

文章目录

  • 前言
  • 一、常量池结构分析
    • 1、常量池位置
    • 2、常量池结构
    • 3、常量池单个常量
    • 4、常量池单个常量 tag 标签
  • 二、常量池字节码文件分析
    • 0、常量池附加信息
    • 1、常量池 #1 常量分析
    • 2、常量池 #2 常量分析
    • 3、常量池 #3 常量分析
    • 4、常量池 #4 常量分析
    • 5、常量池 #5 常量分析
    • 6、常量池 #6 常量分析
    • 7、常量池 #7 常量分析
    • 8、常量池 #8 常量分析
    • 9、常量池 #9 常量分析
    • 10、常量池 #10 常量分析
    • 11、常量池 #11 常量分析
    • 12、常量池 #12 常量分析
    • 13、常量池 #13 常量分析
    • 14、常量池 #14 常量分析
    • 15、常量池 #15 常量分析
    • 16、常量池 #16 常量分析
    • 17、常量池 #17 常量分析
    • 18、常量池 #18 常量分析
    • 19、常量池 #19 常量分析
    • 20、常量池 #20 常量分析
  • 总结

前言

接上一篇博客 【Java 虚拟机原理】Class 字节码二进制文件分析 一 ( 字节码文件附加信息 | 魔数 | 次版本号 | 主版本号 | 常量池个数 ) ;

一、常量池结构分析


1、常量池位置

下图的红框内是常量池 , 在 " 常量池计数器 " 后面的若干字节 ;

在这里插入图片描述

10

10

10 字节及之后的若干字节是常量池范围 ;

在这里插入图片描述

不同的字节码文件 , 常量池的范围是不同的 ;

2、常量池结构

常量池的结构如下 :

在这里插入图片描述

3、常量池单个常量

常量池中的单个常量 : 每个常量 都是如下 cp_info 格式的数据 ;

在这里插入图片描述

4、常量池单个常量 tag 标签

常量池的 tag 以及代表的含义 :

在这里插入图片描述

二、常量池字节码文件分析


0、常量池附加信息

完整的常量池 字节码附加信息 :

Constant pool:
   #1 = Methodref          #4.#17         // java/lang/Object."<init>":()V
   #2 = Fieldref           #3.#18         // Student.name:Ljava/lang/String;
   #3 = Class              #19            // Student
   #4 = Class              #20            // java/lang/Object
   #5 = Utf8               name
   #6 = Utf8               Ljava/lang/String;
   #7 = Utf8               <init>
   #8 = Utf8               ()V
   #9 = Utf8               Code
  #10 = Utf8               LineNumberTable
  #11 = Utf8               getName
  #12 = Utf8               ()Ljava/lang/String;
  #13 = Utf8               setName
  #14 = Utf8               (Ljava/lang/String;)V
  #15 = Utf8               SourceFile
  #16 = Utf8               Student.java
  #17 = NameAndType        #7:#8          // "<init>":()V
  #18 = NameAndType        #5:#6          // name:Ljava/lang/String;
  #19 = Utf8               Student
  #20 = Utf8               java/lang/Object

1、常量池 #1 常量分析

#1 常量分析 : tag 值为 0A ; tag 值为 10 的时候 , 说明该常量是方法引用 ;

在这里插入图片描述

#1 = Methodref          #4.#17         // java/lang/Object."<init>":()V

常量 tag : 0A ;

在这里插入图片描述

常量 info[] : 00 04 00 11 ,

4

4

4 个字节 , 前

2

2

2 个字节代表类信息 , 后

2

2

2 字节代表方法和类型 ;

  • 00 04 类信息 ; 指向常量表中的 #4 常量 ; 类型是 java/lang/Object ;
  • 00 11 方法类型 ; 指向常量表中的 #17 常量 ; 类型是 "<init>":()V ;

在这里插入图片描述

2、常量池 #2 常量分析

#1 常量分析 : tag 值为 09 ; tag 值为 10 的时候 , 说明该常量是字段引用 ;

在这里插入图片描述

   #2 = Fieldref           #3.#18         // Student.name:Ljava/lang/String;

常量 tag : 09 ;

在这里插入图片描述

常量 info[] : 00 03 00 12 ,

4

4

4 个字节 , 前

2

2

2 个字节代表类信息 , 后

2

2

2 字节代表字段名称和类型 ;

  • 00 04 类信息 ; 指向常量表中的 #4 常量 ; 类型是 Student ;
  • 00 11 方法类型 ; 指向常量表中的 #18 常量 ; 类型是 name:Ljava/lang/String ;

在这里插入图片描述

3、常量池 #3 常量分析

#3 常量分析 : tag 值为 07 ; tag 值为 07 的时候 , 类信息 ;

在这里插入图片描述

   #3 = Class              #19            // Student

常量 tag : 07 ;

在这里插入图片描述

常量 info[] : 00 13 ,

2

2

2 个字节 , 指向类名所在常量 ;

  • 00 13 方法类型 ; 指向常量表中的 #19 常量 ; 类名是 Student ;

在这里插入图片描述

4、常量池 #4 常量分析

#4 常量分析 : tag 值为 07 ; tag 值为 07 的时候 , 类信息 ;

在这里插入图片描述

   #4 = Class              #20            // java/lang/Object

常量 tag : 07 ;

在这里插入图片描述

常量 info[] : 00 14 ,

2

2

2 个字节 , 指向类名所在常量 ;

  • 00 14 方法类型 ; 指向常量表中的 #20 常量 ; 类名是 java/lang/Object ;

在这里插入图片描述

5、常量池 #5 常量分析

#5 常量分析 : tag 值为 01 ; 说明该常量是 UTF-8 字符串 ;

在这里插入图片描述

   #5 = Utf8               name

常量 tag : 01 ;

在这里插入图片描述

常量 info[] : 00 04 6E 61 6D 65 ;

  • 00 04 : 表示 UTF-8 字符串 , 有

    4

    4

    4 个字节 ;

  • 6E 61 6D 65 : 字符串内容 name ;

在这里插入图片描述

6、常量池 #6 常量分析

#6 常量分析 : tag 值为 01 ; 说明该常量是 UTF-8 字符串 ;

在这里插入图片描述

   #6 = Utf8               Ljava/lang/String;

常量 tag : 01 ;

在这里插入图片描述

常量 info[] : 00 12 4C 6A 61 76 61 2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B ;

  • 00 12 : 表示 UTF-8 字符串 , 有

    18

    18

    18 个字节 ;

  • 4C 6A 61 76 61 2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B : 字符串内容 Ljava/lang/String; ;

在这里插入图片描述

7、常量池 #7 常量分析

#7 常量分析 : tag 值为 01 ; 说明该常量是 UTF-8 字符串 ;

在这里插入图片描述

   #7 = Utf8               <init>

常量 tag : 01 ;

在这里插入图片描述

常量 info[] : 00 06 3C 69 6E 69 74 3E ;

  • 0006 : 表示 UTF-8 字符串 , 有

    6

    6

    6 个字节 ;

  • 3C 69 6E 69 74 3E : 字符串内容 <init> ;

在这里插入图片描述

8、常量池 #8 常量分析

#8 常量分析 : tag 值为 01 ; 说明该常量是 UTF-8 字符串 ;

在这里插入图片描述

   #8 = Utf8               ()V

常量 tag : 01 ;

在这里插入图片描述

常量 info[] : 00 03 28 29 56 ;

  • 00 03 : 表示 UTF-8 字符串 , 有

    3

    3

    3 个字节 ;

  • 28 29 56 : 字符串内容 ()V ;

在这里插入图片描述

9、常量池 #9 常量分析

#9 常量分析 : tag 值为 01 ; 说明该常量是 UTF-8 字符串 ;

在这里插入图片描述

   #9 = Utf8               Code

常量 tag : 01 ;

常量 info[] : 00 04 43 6F 64 65 ;

  • 00 04 : 表示 UTF-8 字符串 , 有

    4

    4

    4 个字节 ;

  • 43 6F 64 65 : 字符串内容 Code ;

在这里插入图片描述

10、常量池 #10 常量分析

#10 常量分析 : tag 值为 01 ; 说明该常量是 UTF-8 字符串 ;

在这里插入图片描述

  #10 = Utf8               LineNumberTable

常量 tag : 01 ;

常量 info[] : 00 0F 4C 69 6E 65 4E 75 6D 62 65 72 54 61 62 6C 65 ;

  • 00 0F : 表示 UTF-8 字符串 , 有

    15

    15

    15 个字节 ;

  • 4C 69 6E 65 4E 75 6D 62 65 72 54 61 62 6C 65 : 字符串内容 LineNumberTable ;

在这里插入图片描述

11、常量池 #11 常量分析

#11 常量分析 : tag 值为 01 ; 说明该常量是 UTF-8 字符串 ;

在这里插入图片描述

  #11 = Utf8               getName

常量 tag : 01 ;

常量 info[] : 00 07 67 65 74 4E 61 6D 65 ;

  • 00 0F : 表示 UTF-8 字符串 , 有

    15

    15

    15 个字节 ;

  • 00 07 67 65 74 4E 61 6D 65 : 字符串内容 getName ;

在这里插入图片描述

12、常量池 #12 常量分析

#12 常量分析 : tag 值为 01 ; 说明该常量是 UTF-8 字符串 ;

在这里插入图片描述

  #12 = Utf8               ()Ljava/lang/String;

常量 tag : 01 ;

常量 info[] : 00 14 28 29 4C 6A 61 76 61 2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B ;

  • 00 14 : 表示 UTF-8 字符串 , 有

    20

    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; ;

在这里插入图片描述

13、常量池 #13 常量分析

#13 常量分析 : tag 值为 01 ; 说明该常量是 UTF-8 字符串 ;

在这里插入图片描述

  #13 = Utf8               setName

常量 tag : 01 ;

常量 info[] : 00 07 73 65 74 4E 61 6D 65 ;

  • 00 07 : 表示 UTF-8 字符串 , 有

    7

    7

    7 个字节 ;

  • 73 65 74 4E 61 6D 65 : 字符串内容 setName ;

在这里插入图片描述

14、常量池 #14 常量分析

#14 常量分析 : tag 值为 01 ; 说明该常量是 UTF-8 字符串 ;

在这里插入图片描述

  #14 = Utf8               (Ljava/lang/String;)V

常量 tag : 01 ;

常量 info[] : 00 15 28 4C 6A 61 76 61 2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29 56 ;

  • 00 15 : 表示 UTF-8 字符串 , 有

    21

    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 ;

在这里插入图片描述

15、常量池 #15 常量分析

#15 常量分析 : tag 值为 01 ; 说明该常量是 UTF-8 字符串 ;

在这里插入图片描述

  #15 = Utf8               SourceFile

常量 tag : 01 ;

常量 info[] : 00 0A 53 6F 75 72 63 65 46 69 6C 65 ;

  • 00 0A : 表示 UTF-8 字符串 , 有

    10

    10

    10 个字节 ;

  • 53 6F 75 72 63 65 46 69 6C 65 : 字符串内容 SourceFile ;

在这里插入图片描述

16、常量池 #16 常量分析

#16 常量分析 : tag 值为 01 ; 说明该常量是 UTF-8 字符串 ;

在这里插入图片描述

  #16 = Utf8               Student.java

常量 tag : 01 ;

常量 info[] : 00 0C 53 74 75 64 65 6E 74 2E 6A 61 76 61 ;

  • 00 0C : 表示 UTF-8 字符串 , 有

    12

    12

    12 个字节 ;

  • 53 74 75 64 65 6E 74 2E 6A 61 76 61 : 字符串内容 Student.java ;

在这里插入图片描述

17、常量池 #17 常量分析

#17 常量分析 : tag 值为 0C ; 说明该常量是 名称和类型信息 ;

在这里插入图片描述

  #17 = NameAndType        #7:#8          // "<init>":()V

常量 tag : 0C ;

常量 info[] : 00 07 00 08 ;

  • 00 07 : #7 , "<init>" ;
  • 00 08 : #8 , ()V ;

在这里插入图片描述

18、常量池 #18 常量分析

#18 常量分析 : tag 值为 0C ; 说明该常量是 名称和类型信息 ;

在这里插入图片描述

  #18 = NameAndType        #5:#6          // name:Ljava/lang/String;

常量 tag : 0C ;

常量 info[] : 00 05 00 06 ;

  • 00 05 : #5 , name ;
  • 00 06 : #6 , Ljava/lang/String; ;

在这里插入图片描述

19、常量池 #19 常量分析

#19 常量分析 : tag 值为 01 ; 说明该常量是 UTF-8 字符串 ;

在这里插入图片描述

  #19 = Utf8               Student

常量 tag : 01 ;

常量 info[] : 00 07 53 74 75 64 65 6E 74 ;

  • 00 07 : 表示 UTF-8 字符串 , 有

    7

    7

    7 个字节 ;

  • 00 07 53 74 75 64 65 6E 74 : 字符串内容 Student ;

在这里插入图片描述

20、常量池 #20 常量分析

#20 常量分析 : tag 值为 01 ; 说明该常量是 UTF-8 字符串 ;

在这里插入图片描述

  #20 = Utf8               java/lang/Object

常量 tag : 01 ;

常量 info[] : 00 10 6A 61 76 61 2F 6C 61 6E 67 2F 4F 62 6A 65 63 74 ;

  • 00 10 : 表示 UTF-8 字符串 , 有

    16

    16

    16 个字节 ;

  • 6A 61 76 61 2F 6C 61 6E 67 2F 4F 62 6A 65 63 74 : 字符串内容 java/lang/Object ;

在这里插入图片描述

总结

下图的选中区域 , 是整个常量池的范围 ;

在这里插入图片描述

本博客部分图片转载自 https://blog.csdn.net/luanlouis/category_9263262.html 博客

赞(0) 打赏
未经允许不得转载:IDEA激活码 » 【Java 虚拟机原理】Class 字节码二进制文件分析 二 ( 常量池位置 | 常量池结构 | tag | info[] | 完整分析字节码文件中的常量池二进制数据 )

相关推荐

  • 暂无文章

一个分享Java & Python知识的社区