String Pool in Java

2025 年 3 月 27 日 | 阅读 5 分钟

在 Java 中,String 是最重要的主题。与 String 相关有很多概念,而 **字符串常量池概念** 是其中之一。 **Java 中的字符串常量池概念** 有点棘手。因此,在本节中,我们将讨论 **字符串常量池** 或 **字符串驻留概念**。

什么是字符串常量池?

字符串常量池Java 堆 中用于存储字符串字面量的一个存储区域。它也称为 **字符串驻留池** 或 **字符串常量池**。它就像对象分配一样。默认情况下,它是空的,并由 **Java String** 类私有维护。每当我们创建一个字符串时,该字符串对象就会占用堆内存中的一些空间。创建大量字符串可能会增加成本和内存占用,从而降低性能。

JVM 在初始化字符串字面量时会执行一些步骤,这些步骤可以提高性能并减少内存负载。为了减少 JVM 中创建的 String 对象的数量,String 类会维护一个字符串池。

当我们创建一个字符串字面量时,JVM 首先在字符串池中检查该字面量。如果字面量已存在于池中,它将返回池中实例的引用。如果字面量不存在于池中,则会创建一个新的 String 对象并将其放入字符串池中。

在 Java 中创建 String

在 Java 中创建 String 有两种方式:

使用字符串字面量

String str1 = "Python";

String str2 = "Data Science";

String str3 = "Python";

使用 new 关键字

在 Java 中,还可以使用 new 关键字 创建 String,如下所示:

String str1 = new String ("Java");

String str2 = new String ("C++");

String str3 = new String ("Data Science");

让我们了解它们之间的区别。让我们比较字符串字面量的引用。

s1==s3 //true

s2==s3 //false

让我们看看我们是如何发现相等与否的。

String Pool in Java

首先,我们创建了一个字符串字面量 **Python**,它占用了字符串池中的一个位置。之后,创建了字符串 **Data Science**,它也占用了字符串池中的一个位置。最后,我们再次创建了字符串 **Python**。但这次,JVM 检查字符串,发现该字符串字面量已存在。它不会在字符串池中创建新的实例,而是返回池中实例的引用,即 **str1**。

同样,当我们使用 new 关键字创建字符串字面量时,它们也会放入字符串池中。我们创建了三个字符串字面量 **Java, C++,** 和 **Data Science**。我们看到字符串字面量 Java 和 C++ 是新创建的。但是 **Data Science** 字面量已经存在于池中。此时,JVM 为 Java 堆中的字面量 **Data Science** 分配空间。请记住,所有使用 new 关键字创建的字符串字面量都放在 Java 堆中,而不是字符串常量池中。

StringPoolExample.java

输出

String Pool in Java

在上面的示例中,我们看到每当我们使用 **new** 运算符创建字符串时,它都会在 Java 堆中创建一个新的字符串对象。我们可以通过使用 String 类的 **intern()** 方法来强制阻止此功能。

Java String.intern() 方法

**String.intern()** 方法会将字符串放入字符串常量池,或引用字符串常量池中具有相同值的另一个 String 对象。如果字符串常量池已包含与 String 对象值相等的字符串,则它会返回池中的字符串。它通过使用 **String.equals(Object)** 方法来确定字符串。如果字符串不存在,则将 String 对象添加到池中,并返回对该 String 对象的引用。

对于任何两个字符串 str1 和 str2,当且仅当语句 **str1.equals(str2)** 为 true 时,**str1.intern() == str2.intern()** 才为 true。

注意:所有字面量字符串和字符串值的常量表达式都会被驻留。

语法

该方法返回字符串对象的规范表示。

例如

上述语句会在 Java 堆中创建字符串。如果我们要将字符串字面量存储在字符串常量池中,则应使用 intern() 方法。

让我们看一个例子,了解 intern() 方法的用法。

StringInternExample.java

输出

String Pool in Java

注意事项

在处理 String 时,需要牢记有关字符串驻留和字符串常量池的以下几点:

  • String 在 Java 中是不可变的。
  • 所有 String 都存储在 Java 堆中分配的字符串常量池(或字符串驻留池)中。
  • 字符串常量池是字符串驻留概念的一种实现。
  • 字符串驻留是一种只存储每个不同字符串字面量副本的方法。
  • 不同的值存储在字符串常量池中。
  • 字符串常量池是享元设计模式的一个例子。

下一主题Merge-sort-in-java