【JVM】Class结构之常量池

时间:2023-03-09 08:03:06
【JVM】Class结构之常量池

常量池

主要包括下面2类:

  1. 字面量(Literal):如int,double,String等;
  2. 符号引用(Symbolic Reference);

符号引用

  1. 类和接口的全限定名;
  2. 字段的名称和描述符;
  3. 方法的名称和描述符;

当虚拟机运行时,需要从常量池中获取对应的符号引用,再在类创建时或运行时解析、翻译到具体的内存地址之中;

常量池的项目类型(常量类型)

【JVM】Class结构之常量池

常量池中常量项的结构总表

说明: 下图中的tag值即上图中的标志值

【JVM】Class结构之常量池


解析Class文件指令

javap -verbose xxxx

其中xxxx表示的是xxxx.class

如程序TestClass.java


public class TestClass {
private int m; public int inc() {
return m + 1;
}
}

编译后生成的二进制Class文件内容如下:

 Offset: 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
00000000: CA FE BA BE 00 00 00 32 00 16 07 00 02 01 00 09 J~:>...2........
00000010: 54 65 73 74 43 6C 61 73 73 07 00 04 01 00 10 6A TestClass......j
00000020: 61 76 61 2F 6C 61 6E 67 2F 4F 62 6A 65 63 74 01 ava/lang/Object.
00000030: 00 01 6D 01 00 01 49 01 00 06 3C 69 6E 69 74 3E ..m...I...<init>
00000040: 01 00 03 28 29 56 01 00 04 43 6F 64 65 0A 00 03 ...()V...Code...
00000050: 00 0B 0C 00 07 00 08 01 00 0F 4C 69 6E 65 4E 75 ..........LineNu
00000060: 6D 62 65 72 54 61 62 6C 65 01 00 12 4C 6F 63 61 mberTable...Loca
00000070: 6C 56 61 72 69 61 62 6C 65 54 61 62 6C 65 01 00 lVariableTable..
00000080: 04 74 68 69 73 01 00 0B 4C 54 65 73 74 43 6C 61 .this...LTestCla
00000090: 73 73 3B 01 00 03 69 6E 63 01 00 03 28 29 49 09 ss;...inc...()I.
000000a0: 00 01 00 13 0C 00 05 00 06 01 00 0A 53 6F 75 72 ............Sour
000000b0: 63 65 46 69 6C 65 01 00 0E 54 65 73 74 43 6C 61 ceFile...TestCla
000000c0: 73 73 2E 6A 61 76 61 00 21 00 01 00 03 00 00 00 ss.java.!.......
000000d0: 01 00 02 00 05 00 06 00 00 00 02 00 01 00 07 00 ................
000000e0: 08 00 01 00 09 00 00 00 2F 00 01 00 01 00 00 00 ......../.......
000000f0: 05 2A B7 00 0A B1 00 00 00 02 00 0C 00 00 00 06 .*7..1..........
00000100: 00 01 00 00 00 02 00 0D 00 00 00 0C 00 01 00 00 ................
00000110: 00 05 00 0E 00 0F 00 00 00 01 00 10 00 11 00 01 ................
00000120: 00 09 00 00 00 31 00 02 00 01 00 00 00 07 2A B4 .....1........*4
00000130: 00 12 04 60 AC 00 00 00 02 00 0C 00 00 00 06 00 ...`,...........
00000140: 01 00 00 00 06 00 0D 00 00 00 0C 00 01 00 00 00 ................
00000150: 07 00 0E 00 0F 00 00 00 01 00 14 00 00 00 02 00 ................
00000160: 15 .

解析示例:

Offset:00000008~00000009: 0x0016-->22 表示有22-1=21个常量;

使用

javap -verbose TestClass

进行解析,后生成如下:

Compiled from "TestClass.java"
public class TestClass extends java.lang.Object
SourceFile: "TestClass.java"
minor version: 0
major version: 50
Constant pool:
const #1 = class #2; // TestClass
const #2 = Asciz TestClass;
const #3 = class #4; // java/lang/Object
const #4 = Asciz java/lang/Object;
const #5 = Asciz m;
const #6 = Asciz I;
const #7 = Asciz <init>;
const #8 = Asciz ()V;
const #9 = Asciz Code;
const #10 = Method #3.#11; // java/lang/Object."<init>":()V
const #11 = NameAndType #7:#8;// "<init>":()V
const #12 = Asciz LineNumberTable;
const #13 = Asciz LocalVariableTable;
const #14 = Asciz this;
const #15 = Asciz LTestClass;;
const #16 = Asciz inc;
const #17 = Asciz ()I;
const #18 = Field #1.#19; // TestClass.m:I
const #19 = NameAndType #5:#6;// m:I
const #20 = Asciz SourceFile;
const #21 = Asciz TestClass.java; {
public TestClass();
Code:
Stack=1, Locals=1, Args_size=1
0: aload_0
1: invokespecial #10; //Method java/lang/Object."<init>":()V
4: return
LineNumberTable:
line 2: 0 LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this LTestClass; public int inc();
Code:
Stack=2, Locals=1, Args_size=1
0: aload_0
1: getfield #18; //Field m:I
4: iconst_1
5: iadd
6: ireturn
LineNumberTable:
line 6: 0 LocalVariableTable:
Start Length Slot Name Signature
0 7 0 this LTestClass; }