Clintβs answer is fine, but I will continue it further and explain it at the compiler level.
As you know, s1 and s2 will refer to the same instance of the string "Hello" .
For s5 and s6 compiler sees constant expressions. That is, he sees an operation between two constants (string literals). The compiler knows how to add lines and what the result will be. Since the values ββare known immediately at compile time, this addition is for you, leaving the literal string "Hello" . Therefore, it has the same meaning as s1 and s2 , so everyone will refer to the same instance.
s7 cannot be simplified in the same way. s7 first starts with "He" course. The difference here is that s7 = s7.concat("llo"); as reassigning s7 to the result of a function call. It cannot be simplified as it is. As for the Java compiler, the results of all function calls are not known at compile time. Since he does not know the resulting value, it cannot be simplified and left as is. The resulting call returns a new instance of the string "Hello" , which is not the same instance as the compile-time instance (which s8 shares).
s10 also cannot be simplified. s10 first starts with "He" course. Then reassigned s10 = s10 + "llo"; This cannot be simplified. Why can you ask? Well s10 is not a finite variable expression. From a technical point of view, the compiler does not know this value, because it is not a constant. If s10 was declared as final String , then it can be folded (if assigned to another variable).
So, consider this version of the 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 correct?
true, true, false, false, false, true, false
You might be wondering why 3 and 7 are not true. Short answer, the Java compiler was not programmed
to be smart enough to recognize the concat () call, therefore it is treated like a regular function call.