Java中的常量池

type
status
date
slug
summary
tags
category
icon
password

定义

Java中的常量池是Java虚拟机(JVM)中用于存储类所用到的常量的有序集合,主要存放字面量和符号引用量。常量池的存在有助于节省内存空间和运行时间,通过共享对象避免频繁创建和销毁。

分类

静态常量池

静态常量池位于.class文件中,包含字面量和符号引用,用于存储类、方法信息,节省内存和运行时间。静态常量池在类加载时会被读取,并且其内容在编译时就已经确定。
静态常量池中包含的常量类型包括:
  • UTF-8字符串:用于存储文本字符串。
  • 整数、浮点数、长整型、双精度浮点数:用于存储基本数据类型的常量值。
  • 类、字段引用、方法引用:用于存储类和接口的全限定名、字段和方法的名称及描述符。
  • 方法句柄、方法类型、动态常量、调用动态常量:用于表示方法句柄、方法类型、动态计算的常量和调用站点。
  • 模块和包:用于表示模块和包的信息。
静态常量池的结构和内容在类文件中是固定的,不会在运行时发生变化。静态常量池中的常量在类加载时会被加载到运行时常量池中。

运行时常量池

运行时常量池是JVM虚拟机在完成类装载操作后,将静态常量池中的常量载入到内存中,并保存在方法区中。运行时常量池具有动态性,即在运行期间可能有新的常量被添加,如通过String类的intern()方法
运行时常量池的主要作用包括:
  • 存储编译期生成的各种字面量和符号引用:这些常量在运行时会被解析为具体的内存地址。
  • 动态添加常量:在运行期间,可以通过String.intern()方法将新的字符串常量添加到运行时常量池中。
运行时常量池在JDK 1.8之前位于永久代(PermGen),从JDK 1.8开始,永久代被元空间(Metaspace)替代,而运行时常量池仍然位于方法区中。需要注意的是,从JDK 1.7开始,字符串常量池被移到了堆中,而运行时常量池仍然位于方法区。

字符串常量池

字符串常量池是Java堆内存中专门用于存储字符串的一块区域。字符串常量池与常量池不同,字符串常量池是静态的,用于存储字符串对象的引用,避免了重复创建字符串对象。
字符串常量池的主要特点包括:
  • 存储字符串对象的引用:字符串常量池中只存储对java.lang.String实例的引用,而不存储字符串对象的内容。
  • 通过intern()方法添加字符串:可以通过String.intern()方法将堆中的字符串对象设置到字符串常量池中,提高字符串比较的效率。
字符串常量池的使用方式:
  • 直接使用双引号声明:直接声明的字符串对象会放入字符串常量池。
  • 使用new String()创建:通过new String()创建的对象存储在堆内存中。
  • 使用String.intern()方法:将字符串对象放入字符串常量池,如果常量池中已存在该字符串,则返回引用;否则,将新字符串放入常量池并返回引用。

基本类型包装类常量池

Java中的基本类型包装类如ByteShortIntegerLongCharacterBoolean实现了常量池缓存机制。对于特定范围内的数值,会从常量池中取值,超出范围则创建新对象。
比如:
  • Integer:对于-128至127之间的数值,会从常量池中取值,超出范围则创建新对象。
  • Booleantruefalse两个值会被缓存到常量池中。
  • FloatDouble:不实现常量池技术。
Prev
Java的类加载器
Next
MongoDB
Loading...
Article List