接上一篇博客 【Java 虚拟机原理】Class 字节码二进制文件分析 一 ( 字节码文件附加信息 | 魔数 | 次版本号 | 主版本号 | 常量池个数 ) ;
下图的红框内是常量池 , 在 " 常量池计数器 " 后面的若干字节 ;
第
字节及之后的若干字节是常量池范围 ;
不同的字节码文件 , 常量池的范围是不同的 ;
常量池的结构如下 :
常量池中的单个常量 : 每个常量 都是如下 cp_info 格式的数据 ;
常量池的 tag 以及代表的含义 :
完整的常量池 字节码附加信息 :
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 常量分析 : tag 值为 0A
; tag 值为 10 的时候 , 说明该常量是方法引用 ;
#1 = Methodref #4.#17 // java/lang/Object."<init>":()V
常量 tag : 0A
;
常量 info[] : 00 04 00 11
,
个字节 , 前
个字节代表类信息 , 后
字节代表方法和类型 ;
00 04
类信息 ; 指向常量表中的 #4 常量 ; 类型是 java/lang/Object
;00 11
方法类型 ; 指向常量表中的 #17 常量 ; 类型是 "<init>":()V
;#1 常量分析 : tag 值为 09
; tag 值为 10 的时候 , 说明该常量是字段引用 ;
#2 = Fieldref #3.#18 // Student.name:Ljava/lang/String;
常量 tag : 09
;
常量 info[] : 00 03 00 12
,
个字节 , 前
个字节代表类信息 , 后
字节代表字段名称和类型 ;
00 04
类信息 ; 指向常量表中的 #4
常量 ; 类型是 Student
;00 11
方法类型 ; 指向常量表中的 #18
常量 ; 类型是 name:Ljava/lang/String
;#3 常量分析 : tag 值为 07
; tag 值为 07 的时候 , 类信息 ;
#3 = Class #19 // Student
常量 tag : 07
;
常量 info[] : 00 13
,
个字节 , 指向类名所在常量 ;
00 13
方法类型 ; 指向常量表中的 #19
常量 ; 类名是 Student
;#4 常量分析 : tag 值为 07
; tag 值为 07 的时候 , 类信息 ;
#4 = Class #20 // java/lang/Object
常量 tag : 07
;
常量 info[] : 00 14
,
个字节 , 指向类名所在常量 ;
00 14
方法类型 ; 指向常量表中的 #20
常量 ; 类名是 java/lang/Object
;#5 常量分析 : tag 值为 01
; 说明该常量是 UTF-8 字符串 ;
#5 = Utf8 name
常量 tag : 01
;
常量 info[] : 00 04 6E 61 6D 65
;
00 04
: 表示 UTF-8 字符串 , 有 个字节 ;
6E 61 6D 65
: 字符串内容 name
;#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 字符串 , 有 个字节 ;
4C 6A 61 76 61 2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B
: 字符串内容 Ljava/lang/String;
;#7 常量分析 : tag 值为 01
; 说明该常量是 UTF-8 字符串 ;
#7 = Utf8 <init>
常量 tag : 01
;
常量 info[] : 00 06 3C 69 6E 69 74 3E
;
0006
: 表示 UTF-8 字符串 , 有 个字节 ;
3C 69 6E 69 74 3E
: 字符串内容 <init>
;#8 常量分析 : tag 值为 01
; 说明该常量是 UTF-8 字符串 ;
#8 = Utf8 ()V
常量 tag : 01
;
常量 info[] : 00 03 28 29 56
;
00 03
: 表示 UTF-8 字符串 , 有 个字节 ;
28 29 56
: 字符串内容 ()V
;#9 常量分析 : tag 值为 01
; 说明该常量是 UTF-8 字符串 ;
#9 = Utf8 Code
常量 tag : 01
;
常量 info[] : 00 04 43 6F 64 65
;
00 04
: 表示 UTF-8 字符串 , 有 个字节 ;
43 6F 64 65
: 字符串内容 Code
;#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 字符串 , 有 个字节 ;
4C 69 6E 65 4E 75 6D 62 65 72 54 61 62 6C 65
: 字符串内容 LineNumberTable
;#11 常量分析 : tag 值为 01
; 说明该常量是 UTF-8 字符串 ;
#11 = Utf8 getName
常量 tag : 01
;
常量 info[] : 00 07 67 65 74 4E 61 6D 65
;
00 0F
: 表示 UTF-8 字符串 , 有 个字节 ;
00 07 67 65 74 4E 61 6D 65
: 字符串内容 getName
;#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 字符串 , 有 个字节 ;
28 29 4C 6A 61 76 61 2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B
: 字符串内容 ()Ljava/lang/String;
;#13 常量分析 : tag 值为 01
; 说明该常量是 UTF-8 字符串 ;
#13 = Utf8 setName
常量 tag : 01
;
常量 info[] : 00 07 73 65 74 4E 61 6D 65
;
00 07
: 表示 UTF-8 字符串 , 有 个字节 ;
73 65 74 4E 61 6D 65
: 字符串内容 setName
;#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 字符串 , 有 个字节 ;
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 常量分析 : 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 字符串 , 有 个字节 ;
53 6F 75 72 63 65 46 69 6C 65
: 字符串内容 SourceFile
;#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 字符串 , 有 个字节 ;
53 74 75 64 65 6E 74 2E 6A 61 76 61
: 字符串内容 Student.java
;#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 常量分析 : 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 常量分析 : tag 值为 01
; 说明该常量是 UTF-8 字符串 ;
#19 = Utf8 Student
常量 tag : 01
;
常量 info[] : 00 07 53 74 75 64 65 6E 74
;
00 07
: 表示 UTF-8 字符串 , 有 个字节 ;
00 07 53 74 75 64 65 6E 74
: 字符串内容 Student
;#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 字符串 , 有 个字节 ;
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 博客