"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)

查看:144
本文介绍了"a" vs'字符串常量池(JDK 6)中的'new String('a')'vs'new String('a').intern()'的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我曾经知道以下两个语句在运行时在常量池中创建字符串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 present
  • new 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆