JVM 常量池介绍

1,289 阅读5分钟

1、常量池分为字面量常量池和符号引用常量池:

字面量(表示的是值的存储): 1、文本字符串: 定义的字符串常量的值 public String str = “Hello World”; “Hello World” 会存在常量池当中 public String str1 = new String(“Hello Java"); “Hello Java” 的值不会存在常量池中,而是存在堆内存当中

2、final类型的常量值: public final int age = 11; 11的值会存在常量池当中。

3、基本数据类型的值: byte, short, int, float, double, long, char, boolean 并不是所有基本数据类型的值都会存储在常量池中 byte, short, char, boolean 这四种类型的值不会存在常量池中。

无论是文本字符串,还是final类型的常量和基本数据类型的值。其最终存储的类型就是如下: CONSTANT_UTF8: 字符串常量的值 CONSTANT_INTEGER: 四个字节int类型的值 CONSTANT_FLOAT: 四个字节float类型的值 CONSTANT_LONG: 八个字节long类型的值 CONSTANT_DOUBLE: 八个字节double类型的值

符号引用(表示引用的存储): 1、类或者接口的完全限定名: 即是类或者接口的全路径名称。 javap -v 看下 #10 = Class #66 // com/kelvin/jvm/javap/TestConstsPool #66 = Utf8 com/kelvin/jvm/javap/TestConstsPool 10号位置存储的类的名称的引用,引用位置66号。CONSTANT_CLASS类型的常量。 66号位置存储类的全限定名称。CONSTANT_Utf8类型字符串的值

结构类型是: CONSTANT_CLASS:

2、字段的名称和描述符 类中的属性的名称,以及描述属性的描述符(属性的类型)。 private int age = 18; 属性的名称:age 属性的描述符:I (描述符字典表见下)

结构类型是: CONSTANT_Fieldref : 字段的引用(类名.属性名称) CONSTANT_NameAndType:字段或者方式的名称和描述符

3、方法的名称和描述符 描述方法的名称,方法的入参,出参信息 public String getAge(int name) 方法的名称: getAage 方法的描述符: 即表示方法的入参,以及返回值。V代表返回值为空

结构类型: 如果方法没有被使用,则不会放入常量池当中 CONSTANT_Methodref: 方法的引用 (类名.方法的名称) CONSTANT_InterfaceMethodref: 实现接口的方法的引用 CONSTANT_NameAndType:字段或者方式的名称和描述符

类的javap -v 之后的描述:


Classfile /Users/apple/Documents/Projects/MY_GITHUB/distributed/jvm/target/classes/com/kelvin/jvm/javap/TestConstsPool.class
Last modified 2019-5-9; size 1228 bytes
MD5 checksum 62dd2fc4c343ad1213fcdc8b9f6676bd
Compiled from “TestConstsPool.java”
public class com.kelvin.jvm.javap.TestConstsPool implements com.kelvin.jvm.javap.TIF
minor version: 0
major version: 49
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 = Methodref #15.#57 // java/lang/Object.""😦)V
#2 = Fieldref #10.#58 // com/kelvin/jvm/javap/TestConstsPool.i:I
#3 = Fieldref #10.#59 // com/kelvin/jvm/javap/TestConstsPool.aByte:B
#4 = Fieldref #10.#60 // com/kelvin/jvm/javap/TestConstsPool.aShort:S
#5 = Fieldref #10.#61 // com/kelvin/jvm/javap/TestConstsPool.aChar:C
#6 = Fieldref #10.#62 // com/kelvin/jvm/javap/TestConstsPool.aBoolean:Z
#7 = String #63 // Hello World
#8 = Fieldref #10.#64 // com/kelvin/jvm/javap/TestConstsPool.str:Ljava/lang/String;
#9 = Fieldref #10.#65 // com/kelvin/jvm/javap/TestConstsPool.a:I
#10 = Class #66 // com/kelvin/jvm/javap/TestConstsPool
#11 = Methodref #10.#57 // com/kelvin/jvm/javap/TestConstsPool.""😦)V
#12 = Methodref #10.#67 // com/kelvin/jvm/javap/TestConstsPool.setAge:(I)V
#13 = String #68 //
#14 = Methodref #10.#69 // com/kelvin/jvm/javap/TestConstsPool.getAge:(Ljava/lang/String;)I
#15 = Class #70 // java/lang/Object
#16 = Class #71 // com/kelvin/jvm/javap/TIF
#17 = Utf8 i
#18 = Utf8 I
#19 = Utf8 aByte
#20 = Utf8 B
#21 = Utf8 aShort
#22 = Utf8 S
#23 = Utf8 aChar
#24 = Utf8 C
#25 = Utf8 aBoolean
#26 = Utf8 Z
#27 = Utf8 str
#28 = Utf8 Ljava/lang/String;
#29 = Utf8 a
#30 = Utf8 ConstantValue
#31 = Integer 5
#32 = Utf8 b
#33 = Integer 10
#34 = Utf8 
#35 = Utf8 ()V
#36 = Utf8 Code
#37 = Utf8 LineNumberTable
#38 = Utf8 LocalVariableTable
#39 = Utf8 this
#40 = Utf8 Lcom/kelvin/jvm/javap/TestConstsPool;
#41 = Utf8 setAge
#42 = Utf8 (I)V
#43 = Utf8 age
#44 = Utf8 vv
#45 = Utf8 getAge
#46 = Utf8 (Ljava/lang/String;)I
#47 = Utf8 name
#48 = Utf8 main
#49 = Utf8 ([Ljava/lang/String;)V
#50 = Utf8 args
#51 = Utf8 [Ljava/lang/String;
#52 = Utf8 pool
#53 = Utf8 age2
#54 = Utf8 testInterface
#55 = Utf8 SourceFile
#56 = Utf8 TestConstsPool.java
#57 = NameAndType #34:#35 // “”😦)V
#58 = NameAndType #17:#18 // i:I
#59 = NameAndType #19:#20 // aByte:B
#60 = NameAndType #21:#22 // aShort:S
#61 = NameAndType #23:#24 // aChar:C
#62 = NameAndType #25:#26 // aBoolean:Z
#63 = Utf8 Hello World
#64 = NameAndType #27:#28 // str:Ljava/lang/String;
#65 = NameAndType #29:#18 // a:I
#66 = Utf8 com/kelvin/jvm/javap/TestConstsPool
#67 = NameAndType #41:#42 // setAge:(I)V
#68 = Utf8
#69 = NameAndType #45:#46 // getAge:(Ljava/lang/String;)I
#70 = Utf8 java/lang/Object
#71 = Utf8 com/kelvin/jvm/javap/TIF
{
public com.kelvin.jvm.javap.TestConstsPool();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=2, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object.""😦)V
4: aload_0
5: bipush 10
7: putfield #2 // Field i:I
10: aload_0
11: iconst_1
12: putfield #3 // Field aByte:B
15: aload_0
16: iconst_2
17: putfield #4 // Field aShort:S
20: aload_0
21: bipush 115
23: putfield #5 // Field aChar:C
26: aload_0
27: iconst_1
28: putfield #6 // Field aBoolean:Z
31: aload_0
32: ldc #7 // String Hello World
34: putfield #8 // Field str:Ljava/lang/String;
37: aload_0
38: iconst_5
39: putfield #9 // Field a:I
42: return
LineNumberTable:
line 11: 0
line 13: 4
line 14: 10
line 15: 15
line 16: 20
line 17: 26
line 18: 31
line 20: 37
LocalVariableTable:
Start Length Slot Name Signature
0 43 0 this Lcom/kelvin/jvm/javap/TestConstsPool;

public void setAge(int);
descriptor: (I)V
flags: ACC_PUBLIC
Code:
stack=2, locals=3, args_size=2
0: aload_0
1: getfield #2 // Field i:I
4: bipush 10
6: iadd
7: istore_2
8: return
LineNumberTable:
line 25: 0
line 26: 8
LocalVariableTable:
Start Length Slot Name Signature
0 9 0 this Lcom/kelvin/jvm/javap/TestConstsPool;
0 9 1 age I
8 1 2 vv I

public int getAge(java.lang.String);
descriptor: (Ljava/lang/String;)I
flags: ACC_PUBLIC
Code:
stack=1, locals=3, args_size=2
0: aload_0
1: getfield #3 // Field aByte:B
4: istore_2
5: bipush 30
7: ireturn
LineNumberTable:
line 29: 0
line 30: 5
LocalVariableTable:
Start Length Slot Name Signature
0 8 0 this Lcom/kelvin/jvm/javap/TestConstsPool;
0 8 1 name Ljava/lang/String;
5 3 2 a B

public static void main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)V
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=2, locals=3, args_size=1
0: new #10 // class com/kelvin/jvm/javap/TestConstsPool
3: dup
4: invokespecial #11 // Method “”😦)V
7: astore_1
8: aload_1
9: bipush 10
11: invokevirtual #12 // Method setAge:(I)V
14: aload_1
15: ldc #13 // String
17: invokevirtual #14 // Method getAge:(Ljava/lang/String;)I
20: istore_2
21: return
LineNumberTable:
line 34: 0
line 35: 8
line 36: 14
line 37: 21
LocalVariableTable:
Start Length Slot Name Signature
0 22 0 args [Ljava/lang/String;
8 14 1 pool Lcom/kelvin/jvm/javap/TestConstsPool;
21 1 2 age2 I

public void testInterface();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=0, locals=1, args_size=1
0: return
LineNumberTable:
line 41: 0
LocalVariableTable:
Start Length Slot Name Signature
0 1 0 this Lcom/kelvin/jvm/javap/TestConstsPool;
}
SourceFile: “TestConstsPool.java”

参考链接: blog.csdn.net/wangtaomtk/…