关于java String文字池和String的连接的混淆

时间:2013-03-15 08:18:06

标签: java string

全部 我在编写下面的代码时遇到了问题

String hello = "Hello";
String str5 = "Hel" + "lo";
String str8 = "Hel";
String str9 = "lo";
String str10 = str8 + str9;
System.out.println("str10==hello?" + (str10 == hello)); 
System.out.println("str5==hello?" + (str5 == hello));
System.out.println("str10==str5?" + (str10 == str5));

然后我运行我的代码,控制台打印此

str10 == hello ? false
str5 == hello ? true
str10 == str5 ? false
这让我很困惑。为什么第二次打印TRUE但第一次打印FALSE? 在我理解String文字池时,当一个字符串被定义并且JVM将检查池是否包含该字符串时,如果没有,则将该字符串放入池中。
在我的代码中,变量 hello 存在于字符串池中,“ Helo ”和“ lo ”也存在于池中,我的问题是

  1. 如果池中存在“ Helo ”和“ lo ”串联的结果。
  2. 关于str5和str10s的定义有什么区别,为什么它们不是“==”? str5和str10是指字符串池中不同的“ Hello ”吗?(“==”似乎表示引用是同一个对象)
  3. 我的jdk版本:1.6.0_29 我的IDE:Intellij Idea 11.2

    任何人都可以指出来吗?非常感谢你

4 个答案:

答案 0 :(得分:7)

它的行为应该如此。它在JLS的两个部分中得到了解决。

JLS #3.10.5

  作为常量表达式(第15.28节)的值的

字符串是“interned”,以便使用String.intern方法共享唯一的实例。

JLS #15.28列出了被视为常量表达式的内容。特别是,字符串文字是常量表达式(“Hel”和“lo”),但是要将变量视为常量,它必须是最终的。

在您的情况下,如果您稍微更改代码以使str8str9保持不变,您将获得true三次:

final String str8 = "Hel";
final String str9 = "lo";

答案 1 :(得分:1)

String hello = "Hello";       // at compile time string is known so in String Constant Pool

String str5 = "Hel" + "lo";   // at compile time string is known so in String Constant Pool same object as in variable hello

String str8 = "Hel";          // at compile time string is known so in String Constant Pool

String str9 = "lo";           // at compile time string is known so in String Constant Pool

String str10 = str8 + str9;   // at runtime don't know values of str8 and str9 so in String Constant Pool new object different from variable hello

str10 == hello ? false        // as str10 has new object and not the same as in hello

str5 == hello ? true          // both were created at compile time so compiler know what's the result in str5 and referenced the same object to str5 as in hello

str10 == str5 ? false         // str10 is a different object, hello and str5 are referenced same object as created at compile time.

答案 2 :(得分:0)

代码有以下几点需要考虑:

String hello = "Hello";

这里“Hello”是一个分配给引用hello的文字,因此文字有自己的哈希码

String str5 = "Hel" + "lo";

这里“Hel”+“lo”是2个文字组合并分配给引用hello因此新文字与第一个相同,因此相同的哈希码

String str8 = "Hel";
String str9 = "lo";

这里str8 + str9是2个引用,它们组合并指向一个新的引用hello,因此新文本有自己的哈希码

String str10 = str8 + str9;
System.out.println("str10==hello?" + (str10 == hello)); 
System.out.println("str5==hello?" + (str5 == hello));
System.out.println("str10==str5?" + (str10 == str5));

当你使用==它匹配哈希码和值。因此不匹配。

尝试使用

  

string_1.equals(STRING_2)

而不是

  

string_1 == string_2

您将获得价值匹配。因此都是真的

请参阅以下答案(来自What is the difference between == vs equals() in Java?):

equals()方法比较String实例(在堆上)中的“值”,而不管两(2)个对象引用是否引用相同的String实例。如果String类型的任何两(2)个对象引用引用相同的String实例那么棒!如果两(2)个对象引用引用两(2)个不同的String实例,则它没有区别。它是正在比较的每个String实例中的“值”(即:字符数组的内容)。

另一方面,“==”运算符比较两个对象引用的值,以查看它们是否引用相同的String实例。如果两个对象引用的值“引用”相同的String实例,则布尔表达式的结果将为“true”.. duh。另一方面,如果两个对象引用的值“引用”不同的String实例(即使两个String实例具有相同的“值”,也就是说,每个String实例的字符数组的内容都相同)布尔表达式的结果将为“false”。

答案 3 :(得分:-1)

如果您比较两个字符串,请使用string.equals而不是string1 == string2

试一试:

System.out.println("str10==hello?" + (str10.equals(hello));