字符串常量池String Constant Pool
目录
What is a String Constant Pool?什么是字符串常量池?
Important points to remember要记住的要点
How String Constant Pool saves memory?字符串常量池如何节省内存
String constant pool example字符串常量池示例
Output is(输出)
Program Analysis 程序分析
涉及到String类的intern方法
What is a String Constant Pool? 什么是字符串常量池?
One of the main goals of Java programming language is to minimize the redundancy and memory waste/overuse caused by storing String objects with duplicate values on the heap and this is why JVM sets aside a special area on the Heap memory called String Constant Pool.
Java编程语言的主要目标之一是:最小化在堆上存储具有重复值的字符串对象所造成的冗余和内存浪费/过度使用,这就是为什么JVM在堆内存上留出一个称为字符串常量池的特殊区域。
Note : Before we know more String constant pool, we need to remember that a String object can be created with or without using the new keyword.
注意:在了解更多字符串常量池之前,我们需要记住,可以使用或不使用new关键字创建字符串对象。
Important points to remember 要记住的要点
String objects created without the use of new keyword are stored in the String Constant Pool part of the heap.
不使用new关键字创建的字符串对象存储在堆的字符串常量池部分。
String objects created using new keyword are stored in the normal memory part on the heap.
使用new关键字创建的字符串对象存储在堆的普通内存部分。
How String Constant Pool saves memory?字符串常量池如何节省内存?
Now let's understand how String Constant Pool saves memory by a short code :-
现在让我们了解字符串常量池是如何通过一个简短的代码来节省内存的:-
String s1 = "Hello"; // Statement 1
String s2 = "Hello"; // Statement 2
String s3 = new String("Hello"); // Statement 3
After executing these three statements, String constant pool part on heap(a special area on the heap) and the other normal part of heap are represented by Figure 1.
在执行这三个语句之后,堆上的字符串常量池部分(堆上的一个特殊区域)和堆的其他常规部分下图所示。
After executing statement 1, String object with value Hello is stored in String Constant Pool part on the heap because this object is constructed without using the new keyword.
在执行语句1之后,值为Hello的字符串对象存储在堆上的字符串常量池部分中,因为这个对象是在没有使用new关键字的情况下构造的。
Statement 2 asks for the creation of another String object with the same value Hello without using the new keyword.
Before allocating this object on String Constant Pool part of heap memory,JVM checks if there is already a String object with the value Hello present in "String Constant Pool" on the heap and it finds a String object with a similar value Hello being referred by a reference variable s1 already.
语句2要求创建另一个具有相同值Hello的字符串对象,但不使用new关键字。
在堆内存String字符串常量池上分配这个对象之前,JVM在堆上的“字符串常量池”检查是否已经有一个字符串对象值Hello,它发现一个字符串对象的值Hello已经被送到一个引用变量s1。
In order to save the memory from storing a String object with a duplicate value, JVM assigns the reference of the existing String object with value Hello to reference variable s2 as well, thus saving heap memory.
Now reference variables s1, s2 point to same String object with value Hello(Figure 1).
为了节省存储具有重复值的字符串对象的内存,JVM还将具有Hello值的现有字符串对象的引用分配给引用变量s2,从而节省堆内存。
现在,引用变量s1、s2指向与值Hello相同的字符串对象(上图1-Figure1)。
After executing statement 3, String object with a value Hello is created in a normal nonpool part of Heap memory because this object is created using the new keyword.
在执行语句3之后,将在堆内存的普通非池部分中创建具有Hello值的String对象,因为该对象是使用new关键字创建的。
String constant pool example字符串常量池示例
Here in the upcoming program, we have created three String objects and we are using == relational operator,
which checks for equality of references i.e. if two references point to a similar object, to show String Constant Pool saves memory when storing duplicate String objects.
在接下来的程序中,我们创建了三个字符串对象,并使用==关系运算符,
它检查引用是否相等,例如,如果两个引用指向一个相似的对象,以显示字符串常量池在存储重复的字符串对象时节省了内存。
//String Constant Pool Example
class A{
public static void main(String[] args){
String s1 = "Hello"; //creating a String object in String Constant Pool heap.
String s2 = "Hello"; //creating a String object in String Constant Pool with duplicate value.
String s3 = new String("Hello"); //creating String object in the normal heap memory.
String s4 = new String("Hello"); //creating String object in the normal heap memory.
System.out.println("Do s1 and s2 point to a same String object ?"+(s1==s2));
System.out.println("Do s1 and s2 point to a same String object ?"+(s1==s3));
System.out.println("Do s1 and s2 point to a same String object ?"+(s3==s4));
}
}
Output is(输出) :
Do s1 and s2 point to a same String object ?true
Do s1 and s2 point to a same String object ?false
Do s1 and s2 point to a same String object ?false
Program Analysis 程序分析
To avoid storing duplicate String objects on String Constant Pool heap memory,reference variables s1 and s2 refer to the same String object with value Hello on String constant pool memory on the Heap,
whereas, the reference variable s3 and s4 point to objects created in a normal memory on Heap, as these objects were created using the new keyword.
为了避免在字符串常量池堆内存中存储重复的字符串对象,引用变量s1和s2引用在堆上的字符串常量池内存中具有值Hello的相同字符串对象,
但是,引用变量s3和s4指向在堆上的普通内存中创建的对象,因为这些对象是使用new关键字创建的。
Operator == returns true on checking check if references s1 and s2 point to a similar object, which proves that both references, s1 and s2 are pointing to the same object on String constant pools and thus saving memory.
But operator == returns false when reference s1 was compared with s3, because, s1 points to a String object in String Constant Pool memory on the Heap while s3 points to a String object in normal Heap.
操作符==在检查引用s1和s2是否指向类似的对象时返回true,这证明了在字符串常量池中,s1和s2都指向相同的对象,从而节省了内存。
但是,当比较引用s1和s3时,运算符==返回false,因为s1指向堆上的字符串常量池内存中的字符串对象,而s3指向普通堆中的字符串对象。
Finally, operator == returns false when reference s3 was compared with s4.
Although both reference variable s3 and s4 point to the String objects with the same value Hello but as these objects are creating with the new keyword, hence, these objects are stored in normal heap memory where the String objects with duplicate values can be stored.
最后,当引用s3与s4比较时,运算符==返回false。
虽然引用变量s3和s4都指向具有相同值的字符串对象Hello,但是由于这些对象是用new关键字创建的,因此,这些对象存储在普通堆内存中,在那里可以存储具有重复值的字符串对象。
涉及到String类的intern方法
-
intern
public String intern()
Returns a canonical representation for the string object.
返回字符串对象的规范表示形式。A pool of strings, initially empty, is maintained privately by the class
String
.
字符串池最初是空的,由类字符串私下维护。When the intern method is invoked, if the pool already contains a string equal to this
String
object as determined by theequals(Object)
method, then the string from the pool is returned. Otherwise, thisString
object is added to the pool and a reference to thisString
object is returned.
在调用intern方法时,如果池中已经包含了由equals(object)方法确定的与此字符串对象相等的字符串,则返回池中的字符串。否则,该字符串对象将被添加到池中,并返回对该字符串对象的引用。It follows that for any two strings
s
andt
,s.intern() == t.intern()
istrue
if and only ifs.equals(t)
istrue
.
因此,对于任意两个字符串s和t, s.intern() == t.intern()在且仅当s.equals(t)为真时为真All literal strings and string-valued constant expressions are interned. String literals are defined in section 3.10.5 of the The Java™ Language Specification.
所有文本字符串和字符串值常量表达式都是内部连接的。字符串的定义在Java™语言规范的3.10.5节中。- Return返回:
- a string that has the same contents as this string, but is guaranteed to be from a pool of unique strings.
- 具有与此字符串相同的内容,但保证来自唯一字符串池的字符串。