Your code compiles into
public static void main(java.lang.String[]);
Code:
0: ldc #16 // String This is
2: astore_1
3: new #18 // class java/lang/StringBuilder
6: dup
7: aload_1
8: invokestatic #20 // Method java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String;
11: invokespecial #26 // Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V
14: ldc #29 // String my book
16: invokevirtual #31 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
19: invokevirtual #35 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
22: astore_1
23: ldc #39 // String This is my book
25: astore_2
26: getstatic #41 // Field java/lang/System.out:Ljava/io/PrintStream;
29: aload_1
30: aload_2
31: if_acmpne 38
34: iconst_1
35: goto 39
38: iconst_0
39: invokevirtual #47 // Method java/io/PrintStream.println:(Z)V
42: return
which is equivalent to
public static void main(String[] args) {
StringBuilder sb = new StringBuilder("This is ");
sb.append("my book");
String s1 = sb.toString();
String s2 = "This is my book";
System.out.println(s1 == s2);
}
because
s1=s1+"my book";
is not a constant expression - you are reading the value of a variable and the compiler will assume that you could have changed it in the meantime. If you want that
Strings computed by constant expressions (§15.28) are computed at compile time and then treated as if they were literals. JLS (§3.10.5)
applies you would have to change your code to
public static void main(String[] args) {
String s1 = "This is " + "my book";
String s2 = "This is my book";
System.out.println(s1 == s2);
}
or
public static void main(String[] args) {
final String s1a = "This is ";
final String s1b = "my book";
String s1 = s1a + s1b;
String s2 = "This is my book";
System.out.println(s1 == s2);
}
and now you are guaranteed that it works. Second example compiles to
public static void main(java.lang.String[]);
Code:
0: ldc #16 // String This is
2: astore_1
3: ldc #18 // String my book
5: astore_2
6: ldc #20 // String This is my book
8: astore_3
9: ldc #20 // String This is my book
11: astore 4
13: getstatic #22 // Field java/lang/System.out:Ljava/io/PrintStream;
16: aload_3
17: aload 4
19: if_acmpne 26
22: iconst_1
23: goto 27
26: iconst_0
27: invokevirtual #28 // Method java/io/PrintStream.println:(Z)V
30: return
and as you can see loads 2 times String #20