什么是 Java 中的常量池?
什么是 Java 中的常量池?
回答重点
Java 中的常量池(Constant Pool)是一块存储用于运行时的常量或符号的区域。它主要存在于两种地方:
- 运行时常量池:在每个类或接口的
Class文件中存储编译时生成的常量信息,并在类加载时进入 JVM 方法区(Java 8 之后是 metaspace)。 - 字符串常量池:用于存储字符串字面量,位于堆内存中的一块特殊区域。通过
String类中的intern()方法可以将字符串加入到字符串常量池。
常量池的作用:
- 常量池主要用于减少重复对象的创建,节省内存并提高效率。在 Java 编译过程中,一些常用的常量值如字符串、基本类型等会存储在常量池中,避免重复创建相同的常量。
扩展知识
字符串常量池与堆内存
字符串常量池最具代表性。在 Java 中,字符串的创建方式有两种:
- 直接使用字面量:
String s = "Hello";会将"Hello"存储在常量池中,如果常量池中已存在"Hello",则不会重复创建。 - 使用
new关键字:String s = new String("Hello");不论常量池中是否已存在"Hello",都会在堆中创建一个新的String对象。
常量池的存储内容
常量池不仅存储字符串常量,还包括:
- 基本类型的字面量(如整数、浮点数)
- 类和接口的引用
- 方法和字段的符号引用(用于动态链接)
intern() 方法
String.intern() 方法会将字符串加入到字符串常量池中,如果池中已存在该字符串,则返回池中的引用。如果没有,则将当前字符串添加到池中。
1 | String str1 = new String("abc"); |
Java 1.6 和 1.7 关于常量池的差异
在 Java 1.7 的时候,HotSpot 将字符串从运行时常量池(方法区内)中剥离出来,搞了个字符串常量池存储在堆内,因为字符串对象也经常需要被回收,因此放置到堆中好管理回收。
不过按照 Java 虚拟机定义而言,字符串常量池还是属于运行时常量池,只不过 HotSpot 的实现将其放在里堆中而已,逻辑上它还是属于运行时常量池。
Comments