4

以下代码段实习了一个字符串。

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似乎没有被拘留。我在这里俯瞰什么?

我已经在 J​​ava 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");
    }
}
4

3 回答 3

6

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

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

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

于 2013-10-20T21:56:58.237 回答
3

当您使用intern()之前不在字符串池中的字符串时,该字符串将被放置在那里,并且每个下一个文字都将使用对它的引用。

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

由于 Java 在执行方法之前加载并执行了一些代码,main因此有可能在执行代码之前将一些文字放置在字符串池中main
例如,字符串池将包含诸如"UTF-8", "charset",之类的文字"charsetName",它们可能来自java.lang.String, 或java.nio.charset.Charset类。似乎"string"文字就是其中之一(我不确定它到底是在哪里添加到字符串池中的)。

所以当你调用

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

intern不会将"string"fromconcat11放入字符串池中,因为那里已经有一个,而其他"string"文字(例如您=="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

输出

false
true
于 2013-10-20T22:48:31.300 回答
2

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

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

于 2013-10-28T17:42:25.373 回答