What trips you up is this part of the specification:
The String object is newly created (§12.5) unless the expression is a constant expression (§15.28).
So when you concatenate a string constant to another string constant, that counts as a constant expression and therefore will be evaluated at compile time and replaced with the string constant "My Computer".
You can verify this by running javap -c on the compiled class.
public class Test { public static void main(String[] args) { String s1 = "My Computer"; String s2 = "My" + " Computer"; String s3 = "My"; String s4 = s3 + " Computer"; System.out.println(s1 == s2); //true System.out.println(s1 == s4); //false } }
Which compiles to:
public static void main(java.lang.String[]); Code: // s1 = "My Computer" 0: ldc #2 // String My Computer 2: astore_1 // s2 = "My" + " Computer" 3: ldc #2 // String My Computer 5: astore_2 // s3 = "My" 6: ldc #3 // String My 8: astore_3 // s4 = s3 + " Computer" 9: new #4 // class java/lang/StringBuilder 12: dup 13: invokespecial #5 // Method java/lang/StringBuilder."< init>":()V 16: aload_3 17: invokevirtual #6 // Method java/lang/StringBuilder.ap pend:(Ljava/lang/String;)Ljava/lang/StringBuilder; 20: ldc #7 // String Computer 22: invokevirtual #6 // Method java/lang/StringBuilder.ap pend:(Ljava/lang/String;)Ljava/lang/StringBuilder; 25: invokevirtual #8 // Method java/lang/StringBuilder.to String:()Ljava/lang/String; 28: astore 4 ... the rest of the code omitted
As you can see, the first two assignments (to s1 and s2) load exactly the same constant (#2), and therefore use the same object. Whereas the assignment to s4 is not defined as a constant expression (even though a sufficiently clever compiler could figure it out, it is not allowed to), and therefore you get the whole "create a StringBuilder, append the strings to it, convert the result to a new string" process.
As an interesting aside, if in the code above you add the final modifier to s3, that makes s3 + " Computer" a constant expression again, and both comparisons will print true.
And as no doubt you already know, your code's correctness mustn't rely on all of this, but it's a fun thing to know.
s2just consists of two literals, and will combine them to the literalmy computer. Since this literal exists yet,s1ands2are pointing to the same reference ofmy computer.