常量池:
即class文件常量池,是class文件的一部分,用于保存编译时确定的数据。
保存的内容如下图:
1 D:java estoutproduction est>javap -verbose mainTest 2 Classfile /D:/java/test/out/production/test/mainTest.class 3 Last modified 2019年4月22日; size 507 bytes 4 MD5 checksum 08699c6d713bc8967a8daea381ce23c1 5 Compiled from "mainTest.java" 6 public class mainTest 7 minor version: 0 8 major version: 55 9 flags: (0x0021) ACC_PUBLIC, ACC_SUPER 10 this_class: #4 // mainTest 11 super_class: #5 // java/lang/Object 12 interfaces: 0, fields: 1, methods: 2, attributes: 1 13 Constant pool: 14 #1 = Methodref #5.#25 // java/lang/Object."<init>":()V 15 #2 = Fieldref #4.#26 // mainTest.age2:I 16 #3 = String #27 // sss 17 #4 = Class #28 // mainTest 18 #5 = Class #29 // java/lang/Object 19 #6 = Utf8 age2 20 #7 = Utf8 I 21 #8 = Utf8 <init> 22 #9 = Utf8 ()V 23 #10 = Utf8 Code 24 #11 = Utf8 LineNumberTable 25 #12 = Utf8 LocalVariableTable 26 #13 = Utf8 this 27 #14 = Utf8 LmainTest; 28 #15 = Utf8 main 29 #16 = Utf8 ([Ljava/lang/String;)V 30 #17 = Utf8 args 31 #18 = Utf8 [Ljava/lang/String; 32 #19 = Utf8 name 33 #20 = Utf8 Ljava/lang/String; 34 #21 = Utf8 nick 35 #22 = Utf8 age 36 #23 = Utf8 SourceFile 37 #24 = Utf8 mainTest.java 38 #25 = NameAndType #8:#9 // "<init>":()V 39 #26 = NameAndType #6:#7 // age2:I 40 #27 = Utf8 sss 41 #28 = Utf8 mainTest 42 #29 = Utf8 java/lang/Object 43 { 44 public mainTest(); 45 descriptor: ()V 46 flags: (0x0001) ACC_PUBLIC 47 Code: 48 stack=2, locals=1, args_size=1 49 0: aload_0 50 1: invokespecial #1 // Method java/lang/Object."<init>":()V 51 4: aload_0 52 5: bipush 22 53 7: putfield #2 // Field age2:I 54 10: return 55 LineNumberTable: 56 line 1: 0 57 line 2: 4 58 LocalVariableTable: 59 Start Length Slot Name Signature 60 0 11 0 this LmainTest; 61 62 public static void main(java.lang.String[]); 63 descriptor: ([Ljava/lang/String;)V 64 flags: (0x0009) ACC_PUBLIC, ACC_STATIC 65 Code: 66 stack=1, locals=4, args_size=1 67 0: ldc #3 // String sss 68 2: astore_1 69 3: ldc #3 // String sss 70 5: astore_2 71 6: bipush 25 72 8: istore_3 73 9: return 74 LineNumberTable: 75 line 4: 0 76 line 5: 3 77 line 6: 6 78 line 7: 9 79 LocalVariableTable: 80 Start Length Slot Name Signature 81 0 10 0 args [Ljava/lang/String; 82 3 7 1 name Ljava/lang/String; 83 6 4 2 nick Ljava/lang/String; 84 9 1 3 age I 85 } 86 SourceFile: "mainTest.java"
运行时常量池:
Java语言并不要求常量一定只能在编译期产生,运行期间也可能产生新的常量,这些常量被放在运行时常量池中。
类加载后,常量池中的数据会在运行时常量池中存放!
这里所说的常量包括:基本类型包装类(包装类不管理浮点型,整形只会管理-128到127)和String(也可以通过String.intern()方法可以强制将String放入常量池)
字符串常量池:
HotSpot VM里,记录interned string的一个全局表叫做StringTable,它本质上就是个HashSet<String>。注意它只存储对java.lang.String实例的引用,而不存储String对象的内容
jdk 1.7后,移除了方法区间,运行时常量池和字符串常量池都在堆中。