一个关于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文字池的理解中,当定义一个string时,JVM将检查该池是否包含该string,如果没有,则将该string放入池中。
在我的代码中,variableshello存在于string池中,“ Helo ”和“ lo ”也在池中,我的问题是

  1. 如果池中存在“ Helo ”和“ lo ”串联的结果。
  2. str5和str10s的定义有什么区别,为什么不是“==”? str5和str10是指string池中的不同“ Hello ”?(“==”似乎意味着引用是同一个对象)

我的JDK版本:1.6.0_29
我的IDE:Intellij Idea 11.2

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

它的行为应该如此。 这是在JLS的两个部分。

JLS#3.10.5 :

作为常量expression式(第15.28节)值的string是“interned”,以便使用方法String.intern共享唯一的实例。

JLS#15.28列出了什么被认为是一个常量expression式。 特别是,string文字是常量expression式(“Hel”和“lo”),但是对于一个variables被认为是一个常数,它需要是最终的。

在你的情况下,如果你稍微改变你的代码,使str8str9不变,你会得到true三次:

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

代码有以下几点要考虑:

 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

你只会得到价值匹配。 因此都是如此

请参考下面的答案(从Java中的==和equals()之间的区别是什么? ):

equals()方法比较String实例(堆中)的“value”,而不pipe两(2)个对象引用是否引用相同的String实例。 如果任何两(2)个Stringtypes的对象引用指向相同的String实例,那么太棒了! 如果两(2)个对象引用引用了两(2)个不同的string实例,则不会有任何区别。 它是每个正在比较的string实例中的“值”(即:字符数组的内容)。

另一方面,“==”运算符比较两个对象引用的值,以查看它们是否引用相同的String实例。 如果两个对象引用的值“引用”相同的string实例,那么布尔expression式的结果将是“真正的”.. duh。 另一方面,如果两个对象引用的值“引用”不同的string实例(即使两个string实例具有相同的“值”,即每个string实例的字符数组的内容相同),布尔expression式的结果将是“false”。

 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. 

如果你比较两个string使用string.equals不是string1 == string2

尝试一下:

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