For the scenario 1:
String s = new String("1");
s.intern();
String s2 = "1";
System.out.println(s == s2);
with bytecode:
0: new #2 // class java/lang/String
3: dup
4: ldc #3 // String 1
6: invokespecial #4 // Method java/lang/String."<init>":(Ljava/lang/String;)V
9: astore_1
10: aload_1
11: invokevirtual #5 // Method java/lang/String.intern:()Ljava/lang/String;
14: pop
15: ldc #3 // String 1
for String s = new String("1"); it will create a new String object, it will have a new address with "1" that it is already in String Pool:
ldc #3 // String 1
and for s2, as the bytecode:
15: ldc #3 // String 1
s2 is pointing to String Pool variable: "1", so s and s2 have the different address and result is false.
For the scenario 2:
String s3 = new String("1")+new String("1");
s3.intern();
String s4 = "11";
System.out.println(s3 == s4);
with bytecode:
0: new #2 // class java/lang/StringBuilder
3: dup
4: invokespecial #3 // Method java/lang/StringBuilder."<init>":()V
7: astore_1
8: aload_1
9: ldc #4 // String 1
11: invokevirtual #5 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
14: ldc #4 // String 1
16: invokevirtual #5 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
19: invokevirtual #6 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
22: astore_2
23: aload_2
24: invokevirtual #7 // Method java/lang/String.intern:()Ljava/lang/String;
27: astore_3
28: ldc #8 // String 11
As the bytecode, you can see new String("1")+new String("1"); is created by using StringBuilder
new #2 // class java/lang/StringBuilder
it's totally a new Object without String Pool variable.
and after s3.intern(), this method will add current s3 to the Memory String Pool and 8: aload_1.
and s4 is trying to load from
ldc #8 // String 11
so s3 and s4 address should equal and result is true.
s3.intern()after initializings4changes the output tofalse. This seems to indicate that the literal"11"is only retrieved from the pool as the line is executed, which isn't how I understood string literal interning to work.String.intern()should be assigned back to the variable: don't bother. The real question is why the behavior in the two cases (s == s2vss3 == s4) is different.