"a" vs'字符串常量池(JDK 6)中的'new String('a')'vs'new String('a').intern()' [英] "a" vs 'new String("a")' vs 'new String("a").intern()' in String Constant Pool (JDK 6)
问题描述
我曾经知道以下两个语句在运行时在常量池中创建字符串a
:
I used to know that both of the following statements create the string a
in the constant pool at runtime:
String s = "a"
String s = new String("a")
在JVM上测试它们时,两种情况下的permgen大小都是相同的.
When testing these on the JVM, permgen size is the same for both cases.
但是,以下代码段的行为与此不同:
The following code snippets, however, behave differently from this:
String s2 = null;
for (int i = 0; i < 100; i++)
{
s2 = s2 + i;
}
使用.intern()
,每次迭代的permgen大小都会增加:
Using .intern()
, the permgen size increases in each iteration:
String s2 = null;
for (int i = 0; i < 100; i++)
{
s2 = s2 + i;
s2.intern();
}
为什么这种行为是可观察到的? s2.intern()
是否将条目添加到池中?与这些声明有何不同?
Why is this behaviour observable? Does s2.intern()
add entries to the pool? How is this different from these declarations?
String s = "a"
String s = new String("a")
推荐答案
这里有一些解释:
-
"a"
如果没有,请在内部缓冲池中创建字符串"a" -
new String("a")
,因为参数为"a" ,所以在内部存储区(如果尚不存在)中创建了字符串"a" ,并复制了"a" 是从实习生池中创建的 - 采用任何字符串s
s.intern()
返回该字符串的内部副本(如果存在于内部缓冲池中).如果没有,则将该字符串添加到内部池并返回新副本.
"a"
create the String "a" in the intern pool if not already presentnew String("a")
because the parameter is "a", the string "a" is created in the intern pool (if not already present) and a copy of "a" is created out of intern pool- taken any string s
s.intern()
returns an intern copy of that string if present in the intern pool. If not add that string to the intern pool and returns the new copy.
intern()的参考方法:
调用intern方法时,如果池中已经包含一个 等于由equals(Object)确定的此String对象的字符串 方法,然后返回池中的字符串.不然这样 将String对象添加到池中,并对此String进行引用 对象被返回.
When the intern method is invoked, if the pool already contains a string equal to this String object as determined by the equals(Object) method, then the string from the pool is returned. Otherwise, this String object is added to the pool and a reference to this String object is returned.
注意:要创建String
并不要将其添加到内部缓冲池,您可以使用字符数组作为String构造函数的参数:
Note: to create a String
and don't add it to the intern pool you can use an array of chars as parameter of String constructor:
char[] helloArray = { 'h', 'e', 'l', 'l', 'o', '.' };
String helloString = new String(helloArray);
Here is the reference to the jls where it is explained that a string literal is present in the intern pool of strings:
字符串文字是对String类(第4.3.1节,第4.3.3节)的实例的引用.
A string literal is a reference to an instance of class String (§4.3.1, §4.3.3).
此外,字符串文字总是引用类的相同实例 细绳.这是因为字符串文字-或更广泛地说,是字符串 常量表达式的值(第15.28节)-是"interned" 以便使用String.intern方法共享唯一的实例.
Moreover, a string literal always refers to the same instance of class String. This is because string literals - or, more generally, strings that are the values of constant expressions (§15.28) - are "interned" so as to share unique instances, using the method String.intern.
下面是对最后一条评论的逐步说明:
Here a step by step explanation to the last comment:
// Creates the string "123", add it to the intern pool and assign "123" to s
String s = "123";
// s.intern() returns the intern string of s. Because s is already the
// string "123" present in the intern pool s and s.intern() are the same
System.out.println(s == s.intern());// true
// "123" is already in intern pool. new String("123") create a new String
// that equals "123" but it is a different object
String s2 = new String("123");
// It prints false because s2 is equals to "123", but not the same object
// because a new String was created in the preciding row
System.out.println(s2 == s);// false
// It prints true because s2.intern() returns the string present in the
// intern pool that is equals to s2. That string exists and is "123"
System.out.println(s2.intern() == s); // true
附加说明:对于每个等于s2的字符串s,如果s == s2返回false,则s.intern()== s2.intern().
Additional note: For every string s that equals s2, s.intern() == s2.intern() also if s == s2 returns false.
// If s equals s2 but are not the same
if (s.equals(s2) && s != s2) {
// THe intern string of s and s2 are always the same
System.out.println(s.intern() == s2.intern()); // prints always true
}
这篇关于"a" vs'字符串常量池(JDK 6)中的'new String('a')'vs'new String('a').intern()'的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!