The strings s1
through s4
are all compile time constants.
The compiler calculates "He" + "llow"
during compile time, and consults the string pool as to whether the result is already there, and puts it there if it doesn't.
But the calculation of s1 + s2
is not done in compile time, and therefore its result is not interned. Why? Because in theory, another thread could change the value of s1
or s2
so by the time we get to this instruction in the code, it may set s2
to "foo"
, so the result becomes "Hefoo"
.
You, as the author, may know that no thread will be doing that and that these are local variables anyway, but the compiler doesn't.
If you change your definitions to:
final String s1="He";
final String s2="llow";
final String s3="Hellow";
final String s4="He"+"llow";
final String s5=s1+s2;
Then indeed, the result of s5 == s3
will be true
! Why? Because the final
keyword lets the compiler know that these strings are not going to be replaced, they are the final value of these variables. So it can calculate it in compile time and take the result that is already in the pool.