常量池是JVM中用来存储各种字面量和符号引用的表结构,在class文件和运行时都发挥着关键作用 。常见的三种是Class文件常量池、运行时常量池和字符串常量池。
一、什么是常量池?
常量池是Java中存储固定数据的"共享资源库" ,相当于一个存放常量的公共仓库 。它的核心作用是复用重复数据,减少内存占用。Java中有三种常量池协同工作:
二、三种常量池详解
1️⃣ 类文件常量池(菜谱材料单)
- 位置:
.class文件中
- 内容:存放源码中写死的字面量 (如
数字100、字符串"Hello"
)和符号引用(类和接口的全限定名、字段名和描述符、方法名和描述符)
- 特点:静态存储,类似做菜前准备的原料清单
示例:
java
String s1 = "Java";
int num = 100;
2️⃣ 运行时常量池(动态调料台)
- 位置:方法区(元空间)
- 工作阶段:
类加载时
创建 - 特点:将
Class文件常量池
的静态数据转为运行时可用数据,可动态添加新常量,每个类都有自己的运行时常量池,支持动态解析
内存变化示意图: .class文件 → 类加载器 → 方法区(动态生成运行时常量池)
3️⃣ 字符串常量池(共享字条板)
- 位置:JDK1.7后存放在堆内存
- 特点:专门
存放String对象
,实现字符串重用机制
,采用享元模式实现复用 ,实现采用HashTable的数据结构,保证字符串的唯一性。 - 工作机制: new String("ABC") → 堆中创建新对象
"ABC" → 先查池,存在则复用,不存在则新建
运行时常量池演进变化
三、三者关系流程图
四、实战案例对比
java
String a = "Hello"; // 从字符串常量池取
String b = new String("Hello"); // 强制新建对象
System.out.println(a == b); // false(内存地址不同)
System.out.println(a.equals(b)); // true(值相同)
五、记忆技巧
- 文件常量池:静态的纸质清单
- 运行时常量池:动态的电子菜单
- 字符串常量池:共享的食材仓库
- 特殊记忆点:字符串比较用equals(),==比较内存地址
理解常量池能帮助我们:
- ✓ 优化内存使用
- ✓ 避免重复创建对象
- ✓ 深入理解字符串处理机制
- ✓ 提升代码性能调优能力
下次遇到String内存问题时,记得先检查是否合理利用了字符串常量池的特性!