Clint's answer is fine but I'll expand on it further and explain at the compiler level.
As you know, s1
and s2
will end up being references to the same string instance, "Hello"
.
For s5
and s6
, the compiler sees constant expressions. That is, it sees an operation between two constants (the string literals). The compiler knows how to add strings and what the result would be. Since the values are known immediately at compile time, it does the addition for you, resulting in the literal string "Hello"
. Consequently, it has the same value as s1
and s2
so each will refer to the same instance as well.
s7
cannot be simplified the same way. s7
initially starts with "He"
of course. The difference here is that s7 = s7.concat("llo");
as reassigning s7
to the result of a function call. This could not be simplified as is. As far as the Java compiler is concerned, the results of all function calls are not known at compile time. Since it doesn't know the resulting value, it cannot be simplified and is left as is. The resulting call returns a new instance of a "Hello"
string which is not the same instance as the compile-time instance (which s8
shares).
s10
cannot be simplified the same way as well. s10
initially starts with "He"
of course. Then is reassigned s10 = s10 + "llo";
This could not be simplified. Why you might ask? Well s10
is a non-final variable expression. Meaning technically, the compiler doesn't know it's value because it isn't a constant. If s10
was declared a final String
, then this could be constant folded (when assigned to a different variable).
So consider this version of your test code:
public static void main(String[] args)
{
String s1 = "Hello";
String s2 = "Hello";
System.out.println("1: s1 == s2 " + (s1 == s2)); // 1
String s3 = "Hel" + "lo";
String s4 = "Hel".concat("lo");
System.out.println("2: s1 == s3 " + (s1 == s3)); // 2
System.out.println("3: s1 == s4 " + (s1 == s4)); // 3
String he = "He";
String s5 = he + "llo";
String s6 = he.concat("llo");
System.out.println("4: s1 == s5 " + (s1 == s5)); // 4
System.out.println("5: s1 == s6 " + (s1 == s6)); // 5
final String fhe = "He";
String s7 = fhe + "llo";
String s8 = fhe.concat("llo");
System.out.println("6: s1 == s7 " + (s1 == s7)); // 6
System.out.println("7: s1 == s8 " + (s1 == s8)); // 7
}
Can you figure out which lines are true?
true, true, false, false, false, true, false
You might be wondering why the 3 and 7 aren't true. Short answer, the Java compiler wasn't programmed
to be smart enough to recognize the concat() call so is treated as a regular function call.