a confusion about java String literal pool and String's concatenation

all, i faced a problem when a write the code below

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

then i run my code and the console print this

str10 == hello ? false
str5 == hello ? true
str10 == str5 ? false

this confused me a lot. why the second print TRUE but the first print FALSE?? in my comprehension of String literal pool,when a string defined and JVM will check if the pool contains that string,if not ,put the string into the pool.
in my code,variable hello exists in string pool,"Helo" and "lo" also in the pool,my question is

  1. if the result of the concatenation of "Helo" and "lo" exists in the pool.
  2. what's the difference between the definition about str5 and str10s',and why they are not "=="? does str5 and str10 refer to the diffrent "Hello” that in the string pool?("==" seems to mean the reference is the same object)

my jdk version :1.6.0_29
my IDE:Intellij Idea 11.2

anyone can point it out? thank you very much


Solution 1:

It behaves as it should. It is adressed in two sections of the JLS.

JLS #3.10.5:

strings that are the values of constant expressions (§15.28) - are "interned" so as to share unique instances, using the method String.intern.

JLS #15.28 lists what is considered as a constant expression. In particular, string literals are constant expressions ("Hel" and "lo") but for a variable to be considered a constant, it needs to be final.

In your case, if you change your code slightly to make str8 and str9 constant, you will get true three times:

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

Solution 2:

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.