美文网首页工作生活
JVM_字节码:字节码常量池结构与描述符

JVM_字节码:字节码常量池结构与描述符

作者: CalmHeart | 来源:发表于2019-07-03 23:47 被阅读0次
Constant pool://常量池
   序号  类型               引用  
   #1 = Methodref          #4.#20         // java/lang/Object."<init>":()V
   #2 = Fieldref           #3.#21         // com/compass/spring_lecture/binarycode/MyTest1.a:I
   #3 = Class              #22            // com/compass/spring_lecture/binarycode/MyTest1
   #4 = Class              #23            // java/lang/Object
   #5 = Utf8               a
   #6 = Utf8               I
   #7 = Utf8               <init>
   #8 = Utf8               ()V
   #9 = Utf8               Code
  #10 = Utf8               LineNumberTable
  #11 = Utf8               LocalVariableTable
  #12 = Utf8               this
  #13 = Utf8               Lcom/compass/spring_lecture/binarycode/MyTest1;
  #14 = Utf8               getA
  #15 = Utf8               ()I
  #16 = Utf8               setA
  #17 = Utf8               (I)V
  #18 = Utf8               SourceFile
  #19 = Utf8               MyTest1.java


  #20 = NameAndType        #7:#8          // "<init>":()V
  #21 = NameAndType        #5:#6          // a:I
  
  #22 = Utf8               com/compass/spring_lecture/binarycode/MyTest1
  #23 = Utf8               java/lang/Object
  1. 使用javap -verbose 命令分析一个字节码文件时,将会分析该字节码文件的魔数、版本号、常量池、类信息、类的构造方法、类的方法信息、类变量和成员变量等信息。

  2. 魔数:magic number 所有的.class字节码文件的前4个字节都是魔数,魔数值是固定值:0xCAFEBABE.咖啡宝贝

  3. 魔数之后的4个字节为版本信息,前2个字节表示minor version(次版本号),后2个字节表示major version(主版本号) 这里的版本号为 00 00 00 34,换算成十进制表示次版本号为0,而主版本号为52 (jdk8) 所以该文件的版本号为1.8.0,可以通过 java -version命令来验证这一点。
    安装的jdk可以通过这个版本号来确定这个class文件是否能够加载,JDK是向下兼容的,1.8的版本可以加载version<1.8的jdk编译的class文件。

  4. 常量池(constant pool):紧接着主版本号之后的就是常量池入口,常量池的长度是不确定的,一个java类中定义的很多信息都是由常量池来维护和描述的,可以将常量池看作是class文件的资源仓库,比如说java类中定义的方法与变量信息,都是存储在常量池中的,常量池中主要存储两类常量:字面量和符号引用[符号引用转换成直接引用]。字面量比如说文本字符串,java中声明为final的常量值等。而符号引用如类和接口的全局限定名,字段的名称和描述符,方法的名称和描述符等。

  5. 常量池的总体结构:
    java类对应的常量池主要由常量池数量和常量池数组(表结构)这2部分共同组成,可以最大限度地压缩字节码的体积,常量池数量紧跟在主版本后面,占据2个字节,常量池数组紧跟在常量池数量之后。常量池数组与一般的数组不同的是,常量池数组中不同的元素的类型、结构都是不同的。长度当然也就不同,但是每一种元素的第一个数据都是一个u1类型,该字节是一个标志位,占据一个1个字节,JVM在解析常量池的时候,会根据这个u1类型来获取对应元素的具体类型。分析字节码:00 18 共有24个常量,反编译字节码中只有23个。为什么呢? 值得注意的是:常量池中元素的个数=常量池数-1(其中0暂时不使用)。目的是满足某些常量池索引值的数据在特定的情况下需要表达[不引用任何的常量池]的含义,根本原因在于,索引为0也是一个常量(保留常量),只不过它不位于常量表中。这个常量就对应null值,索引常量池的索引从1而非0开始。

  6. 在JVM规范中,每个变量/字段都有描述信息,描述信息主要的作用是描述字段的数据类型、方法的参数列表(包括数量、类型与顺序)与返回值,根据描述符的规则,基本数据类型和代表无返回值的void类型都用一个大写字符表示,对象类型则使用字符L加上对象的全局限定名称来表示。为了压缩字节码文件的体积,对于基本的数据类型,JVM都只是用一个大写字母来表示,如下所示:B-byte,C-char,D-double,I-int,F-float,J-long,S-short,Z-boolean,V-void ,L-对象类型,如Ljava/lang/String;

  7. 对于数组类型来说,每一个维度使用一个前置的[表示,如int[]被记录成[I,String[][]被记录成[[Ljava/lang/String;

  8. 用描述符来描述方法的时候,按先参数列表后返回值的顺序进行描述,参数列表按照参数的严格顺序放在一组()之内,如方法 String getNameByAndIdcNo(int id,String idcNo)的描述符为:(I,Ljava/lang/String;)getNameByAndIdcNo Ljava/lang/String;


Utf8类型是01
Methodref是10
Fieldref是9
Class是7
NameAndType是12


分析过程:

07 7 根据类型表找到对应的类型是CONSTANT_Class_info :
index(U2) 00 16(22 指向全限定名常量项的索引)
#3 = Class              #22            // com/compass/spring_lecture/binarycode/MyTest1
#22 = Utf8               com/compass/spring_lecture/binarycode/MyTest1
---
07 表示7 根据类型表找到对应的类型是CONSTANT_Class_info :
index(U2) 00 17(23 指向全限定名常量项的索引)
#4 = Class              #23            // java/lang/Object
##23 = Utf8               java/lang/Object
---
01 表示1 根据类型表找到对应的类型是CONSTANT_utf8_info:
length(U2) 00 01 (1 表示utf8编码的字符串长度)长度是1
byte(U1) 61 (97 表示长度为length的utf8编码的字符串)表示a
#5 = Utf8               a
---
01 表示1 根据类型表找到对应的类型是CONSTANT_utf8_info:
length(U2) 00 01 (1 表示utf8编码的字符串长度)长度是1
byte(U1) 49 (73 表示长度为length的utf8编码的字符串)表示I(A:65 B:66...I:73)
#6 = Utf8               I
---
#7 = Utf8               <init>
查看对应的ASCII表
http://ascii.911cha.com/
....

ca fe ba be 00 00 00 34 00 18
-----------------------------------------------常量池开始
0a 00 04 00 14 09
00 03 00 15 07 00 16 07 00 17 01 00 01 61 01 00
01 49 01 00 06 3c 69 6e 69 74 3e 01 00 03 28 29
56 01 00 04 43 6f 64 65 01 00 0f 4c 69 6e 65 4e
75 6d 62 65 72 54 61 62 6c 65 01 00 12 4c 6f 63
61 6c 56 61 72 69 61 62 6c 65 54 61 62 6c 65 01
00 04 74 68 69 73 01 00 2f 4c 63 6f 6d 2f 63 6f
6d 70 61 73 73 2f 73 70 72 69 6e 67 5f 6c 65 63
74 75 72 65 2f 62 69 6e 61 72 79 63 6f 64 65 2f
4d 79 54 65 73 74 31 3b 01 00 04 67 65 74 41 01
00 03 28 29 49 01 00 04 73 65 74 41 01 00 04 28
49 29 56 01 00 0a 53 6f 75 72 63 65 46 69 6c 65
01 00 0c 4d 79 54 65 73 74 31 2e 6a 61 76 61 0c
00 07 00 08 0c 00 05 00 06 01 00 2d 63 6f 6d 2f
63 6f 6d 70 61 73 73 2f 73 70 72 69 6e 67 5f 6c
65 63 74 75 72 65 2f 62 69 6e 61 72 79 63 6f 64
65 2f 4d 79 54 65 73 74 31 01 00 10 6a 61 76 61
2f 6c 61 6e 67 2f 4f 62 6a 65 63 74 
-----------------------------------------------常量池结束
00 21 00 03
00 04 00 00 00 01 00 02 00 05 00 06 00 00 00 03
00 01 00 07 00 08 00 01 00 09 00 00 00 38 00 02
00 01 00 00 00 0a 2a b7 00 01 2a 04 b5 00 02 b1
00 00 00 02 00 0a 00 00 00 0a 00 02 00 00 00 04
00 04 00 06 00 0b 00 00 00 0c 00 01 00 00 00 0a
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
ac 00 00 00 02 00 0a 00 00 00 06 00 01 00 00 00
0a 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 01 00 09 00 00 00
3e 00 02 00 02 00 00 00 06 2a 1b b5 00 02 b1 00
00 00 02 00 0a 00 00 00 0a 00 02 00 00 00 0e 00
05 00 0f 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
01 00 12 00 00 00 02 00 13

相关文章

  • JVM_字节码:字节码常量池结构与描述符

    使用javap -verbose 命令分析一个字节码文件时,将会分析该字节码文件的魔数、版本号、常量池、类信息、类...

  • JVM_字节码:字节码常量池分析

    分析的条件: 基于上一篇的16进制字节码及反编译结果(javap -verbose the desire clas...

  • Java虚拟机-字节码指令

    1 字节码指令 Java字节码指令的执行离不开操作数栈,局部变量表,和常量池。 2 常量池 对于字节码指定来说,常...

  • 第二章 中间表示

    java字节码作为中间表示(使用javap命令查看) baf中间表示把200多种不同的字节码精简为60种没有常量池...

  • 字节码解析

    一个普通的Java类与其字节码举例: 字节码中包含哪些内容? 魔数(0xCAFEBABE)、版本号、常量池、访问标...

  • JVM_字节码:字节码相关概述

    Java字节码的整体结构: Class字节码中有两种数据类型: 字节码数据直接量:这是基本的数据类型,共细分为u1...

  • Java字节码常量池

    引言 上篇文章简单介绍了java Class 字节码文件的基本格式。本文我们直接通过阅读字节码文件来进一步理解字节...

  • java 字节码

    字节码: 1: 字节码结构,class文件的二进制文件意义2: 现有的字节码技术,asm与javasist3: d...

  • 字节码引用检测原理与实战

    一、字节码与引用检测 1.1 Java字节码 本章中的字节码重点研究Java 字节码,Java字节码(Java b...

  • 11_JVM学习笔记_字节码剖析

    字节码剖析 示例代码: 反编译信息如下: 字节码文件16进制 Java字节码结构 Class字节码中有两种数据类型...

网友评论

    本文标题:JVM_字节码:字节码常量池结构与描述符

    本文链接:https://www.haomeiwen.com/subject/mwxmcctx.html