Java中的实习字符串

时间:2013-10-20 21:50:51

标签: java string string-interning

以下代码段实习字符串。

String str1="my";
String str2="string";
String concat1=str1+str2;
concat1.intern();

System.out.println(concat1=="mystring");

表达式concat1=="mystring"返回true,因为concat1已被实习。


如果给定的字符串mystring更改为string,如下面的代码段所示。

String str11="str";
String str12="ing";
String concat11=str11+str12;
concat11.intern();

System.out.println(concat11=="string");

比较表达式concat11=="string"返回false。由concat11保留的字符串似乎没有被实习。我在这里俯瞰什么?

我已经在Java 7上进行了测试,更新了11。


修改

整个代码:

package test;

public final class Test
{
    public static void main(String... args)
    {
        String str11="my";
        String str12="string";
        String concat11=str11+str12;
        concat11.intern();
        System.out.println(concat11=="mystring");

        String str1="str";
        String str2="ing";
        String concat1=str1+str2;
        concat1.intern();
        System.out.println(concat1=="string");
    }
}

3 个答案:

答案 0 :(得分:6)

如果您在同一个程序中运行这两个代码段,则concat1.intern()会将concat1添加到实习字符串池中。但是concat11.intern()不会向池中添加任何内容,因为"string"已经在池中(来自str2)。因此,您的上一次比较是将concat11str2进行比较 - 这些不是同一个对象。

来自http://docs.oracle.com/javase/6/docs/api/index.html?java/lang/String.html的Javadoc

  

当调用intern方法时,如果池已经包含一个等于此String对象的字符串(由equals(Object)方法确定),则返回池中的字符串。否则,将此String对象添加到池中,并返回对此String对象的引用。

答案 1 :(得分:3)

当您对字符串池中不在字符串池中的字符串使用intern()时,此字符串将放在那里,并且每个下一个字面值都将使用对它的引用。

但是如果字符串池中已经存在一些文字,并且您将尝试在具有相同字符的新创建的字符串对象上调用intern(),则它将不会被放置在池中,而只会返回对池中字符串的引用。此外,它不会更改对调用intern的原始字符串的引用。

由于Java在执行main方法之前加载并执行了一些代码,因此在执行main代码之前,有可能会在字符串池中放置一些文字。
例如,字符串池将包含"UTF-8""charset""charsetName"等文字,可能来自java.lang.Stringjava.nio.charset.Charset类。似乎"string"字面值是其中之一(我不确定它在字符串池中的确切位置)。

所以当你调用

String str11="str";
String str12="ing";
String concat11=str11+str12;
concat11.intern();

您的intern不会将"string"concat11放入字符串池中,因为已存在一个"string"文字(例如您在{{1}中使用的文字) } part)将使用字符串池中的那个,而不是来自=="string"

让我们测试一下这个理论:

concat11

输出

String s = "ABCdef";// this string will be placed in 
                    // string pool before rest of code

String str1 = "ABC";
String str2 = "def";
String concat1 = str1 + str2;
concat1.intern();//this will only return reference to literal from pool

System.out.println(concat1 == "ABCdef");//false


// here we don't have any "ABcd" literal in pool yet
String strA = "AB";
String strB = "cd";
String concatAB = strA + strB;
concatAB.intern();//so this will put String object from concatAB to pool
System.out.println(concatAB == "ABcd");//and "ABcd" literal will use same object

答案 2 :(得分:2)

创建字符串并且池中已存在该字符串时,将返回现有字符串的引用,而不是创建新对象并返回其引用。

参考此网站http://java.dzone.com/articles/why-string-immutable-java