存储内容
Class文件中除了有类的版本、字段、方法、接口等描述信息外,还有一项信息是常量池,用于存放编
译期生成的各种字面量和符号引用,这部分内容将在类加载后进入方法区的运行时常量池中存放。
字面量:
双引号引起来的字符串值,“kkb”
定义为final类型的常量的值。
符号引用:
类或接口的全限定名(包括他的父类和所实现的接口)
变量或方法的名称
变量或方法的描述信息
方法的描述:参数个数、参数类型、方法返回类型等等
变量的描述信息:变量的返回值
this
运行时常量池相对于Class文件常量池的另外一个重要特征是具备动态性,Java语言并不要求常量一定
只有编译期才能产生,也就是并非预置入Class文件中常量池的内容才能进入方法区运行时常量池,运
行期间也可能将新的常量放入池中,这种特性被开发人员利用比较多的就是String类的intern()方
法。
存储位置
在JDK1.6及以前,运行时常量池是方法区的一部分。
在JDK1.7及以后,运行时常量池在Java 堆(Heap)中。
运行时和class常量池一样,运行时常量池也是每个类都有一个。但是字符串常量池全只有一个
常量池区别
class常量池(静态常量池)、运行时常量池、字符串常量池区别:
1.class常量池中存储的是符号引用,而运行时常量池存储的是被解析之后的直接引用。
2.class常量池存在于class文件中,运行时常量池和字符串常量池是存在于JVM内存中。
3.运行时常量池具有动态性,java运行期间也可能将新的常量放入池中(String#intern()),
4.字符串常量池逻辑上属于运行时常量池的一部分,但是它和运行时常量池的区别在于,字符串常量池是全局唯一的,而运行时常量池是每个类一个。
结论
1、单独使用””引号创建的字符串都是常量,编译期就已经确定存储到String Pool中。
2、使用new String(“”)创建的对象会存储到heap中,是运行期新创建的。
3、使用只包含常量的字符串连接符如”aa”+”bb”创建的也是常量,编译期就能确定已经存储到String Pool中。
4、使用包含变量的字符串连接如”aa”+s创建的对象是运行期才创建的,存储到heap中。
5、运行期调用String的intern()方法可以向String Pool中动态添加对象。