程序员程序园程序员技术栈

详解 JVM 字节码(3)

2019-05-03  本文已影响5人  zidea
jvm

版本信息

上一次我们分析前 4 个字节为魔数,继续向下数 4 字节为版本号信息(前两个字节表示此版本号,后两个字节表示主版本号)
00 00 00 36 。36 是 16 进制进行换算 3 * 16 + 6 = 54 这里用的 java 的版本号 10.0.1 版本。

 minor version: 0
 major version: 54

常量池

接下来就是常量池,常量池大小是不固定的。

常量池定义与作用

Java 类中定义的很多信息都是由常量池来维护和描述的。而且字节码其他部分都会引用常量池的内容。所以将常量池看成 Java 类资源仓库。
主要存储两类常量

常量池的结构
   #1 = Methodref          #6.#28         // java/lang/Object."<init>":()V
   #2 = String             #29            // basic
   #3 = Fieldref           #5.#30         // com/zidea/Tut.title:Ljava/lang/String;
   #4 = Fieldref           #5.#31         // com/zidea/Tut.courses:I
   #5 = Class              #32            // com/zidea/Tut
   #6 = Class              #33            // java/lang/Object
   #7 = Utf8               title
   #8 = Utf8               Ljava/lang/String;
   #9 = Utf8               courses
  #10 = Utf8               I
  #11 = Utf8               <init>
  #12 = Utf8               ()V
  #13 = Utf8               Code
  #14 = Utf8               LineNumberTable
  #15 = Utf8               LocalVariableTable
  #16 = Utf8               this
  #17 = Utf8               Lcom/zidea/Tut;
  #18 = Utf8               getTitle
  #19 = Utf8               ()Ljava/lang/String;
  #20 = Utf8               setTitle
  #21 = Utf8               (Ljava/lang/String;)V
  #22 = Utf8               getCourses
  #23 = Utf8               ()I
  #24 = Utf8               setCourses
  #25 = Utf8               (I)V
  #26 = Utf8               SourceFile
  #27 = Utf8               Tut.java
  #28 = NameAndType        #11:#12        // "<init>":()V
  #29 = Utf8               basic
  #30 = NameAndType        #7:#8          // title:Ljava/lang/String;
  #31 = NameAndType        #9:#10         // courses:I
  #32 = Utf8               com/zidea/Tut
  #33 = Utf8               java/lang/Object

为什么是 33 而不是 34,常量池数组个数等于常量池数 - 1 ,其中 0 暂时不使用,索引为 0 是 JVM 保留常量,这个常量不位于常量池,这个常量对应 null

常量池11种数据类型的结构表

这个表不用记,学会查表就行
tag - U1 表示常量类型

1. java/lang/Object."<init>":()V

0A: 10
对应查表 U1 为 10 是 CONSTANT_Methodref_Info
00 06 (6)index: 指向声明方法的类描述符CONSTANT_Class_Info的索引项
00 1C(对应十进制 28) index: 指向名称及类型描述符 CONSTANT_NameAndType_Info的索引项

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

public void setTitle(String title)

编译为字节码(Ljava/lang/String;)V

2. basic

08 标识符对应 CONSTANT_String_Info

3. com/zidea/Tut.title:Ljava/lang/String;

09 标识符对应 CONSTANT_Fieldref_Info

4. com/zidea/Tut.courses:I

09 标识符 CONSTANT_Fieldref_Info
00 05 (5)重复就不多解释了,代表类
00 1F (31)

31 = NameAndType #9:#10 // courses:I

以上就结束两个变量的声明

5. com/zidea/Tut

07 对应标识符为 CONSTANT_Class_Info
00 20 (32) 指向全局限定名常量项的索引

32 = Utf8 com/zidea/Tut

这个类全限定名称

6. java/lang/Object

又是 07 大家自己尝试分析

7. title

01 标识符为 CONSTANT_utf8_Info

8. Ljava/lang/String;
9. courses
10. I

...

#33 = Utf8 java/lang/Object

我相信大家已经了回了怎么进行分析,大家可以自己完成。

这两号表示当前的字节码文件是由那个文件编译出来的。

26 = Utf8 SourceFile

27 = Utf8 Tut.java

在字节码使用/代替.分隔符。

32 = Utf8 com/zidea/Tut

上一篇 下一篇

猜你喜欢

热点阅读