1. 运行时常量池(Runtime Constant Pool)
代码体现:
- 运行时常量池主要包含:类或接口的常量(如字面量、方法名、字段名、描述符等)和符号引用。
- 它从
.class 文件中加载,Java 1.7 之前存储在方法区中,在Java 1.7 的时候, HotSpot将字符串从运行时常量池(方法区内)中剥离出来,搞了个字符串常量池存储在堆内,因为字符串对象也经常需要被回收,因此放置到堆中好管理回收。
public class ConstantPoolExample {
public static final int CONSTANT_INT = 42;
public static final String CONSTANT_STRING = "Hello";
}
解释:
CONSTANT_INT:
42 是编译期常量,在 .class 文件的常量池中存储。- 加载类时进入运行时常量池。
CONSTANT_STRING:
"Hello" 是字符串字面量,存储在字符串常量池中。
2. 字符串常量池(String Constant Pool)
代码体现:
- 字符串常量池专门用于存储字符串字面量,位于堆内存中的一块特殊区域。
String 对象通过字面量创建时会存储到字符串常量池中;如果是通过 new 创建,则存储在堆内存中。
public class StringConstantPoolExample {
public static void main(String[] args) {
String s1 = "Hello";
String s2 = "Hello";
String s3 = new String("Hello");
String s4 = s3.intern();
System.out.println(s1 == s2);
System.out.println(s1 == s3);
System.out.println(s1 == s4);
}
}
解释:
s1 和 s2 都是字面量,指向字符串常量池中的同一个对象。s3 是通过 new 创建,指向堆中的一个新对象。s4 是通过 intern() 方法,返回了常量池中的对象引用。