Since "HelloWorld"
is in the source file, the generated .class
file contains that string constant, and the string constant is added to the String constant pool (SCP) when the class definition is loaded into the JVM.
That means that we would expect s2
, s3
, and s4
to all refer to the string in the SCP.
Don't know why "Hello".concat("World")
ends up referring to the SCP instance, though it's likely an optimization that's implemented in the JVM, because concat()
is a well-known string method, and strings are well-known to be memory hogs.
In contrast, "Hello" + "World"
would also be expected to refer to the SCP instance, because the Java compiler can evaluate that constant expression to "HelloWorld"
, as can be seen if disassembling the .class
bytecode using javap
.
UPDATED
It seems that I was mistaken, and string constants in the .class
file are not added to the SCP when the class is loaded, but when the string constant is first used.
Which means that the sequence is as follows:
s1
is assign string "HelloWorld"
, which is not in SCP.
s1.intern()
adds the string referenced by s1
to the SCP, and s2
is assigned that same reference value.
Result: s2 = s1
String constant "HelloWorld"
is resolved by the JVM, and since it is already in SCP, the SCP instance is returned.
Result: s3 = s1
s3.intern()
simply returns s3
since it's already in SCP.
Result: s4 = s3 = s1
The result is as seen: s1
, s2
, s3
, and s4
all reference the same object.
If the order of the code is changed, the result is different, leading credence to this:
String s1 = "HelloWorld";
String s2 = s1.intern();
String s3 = "Hello".concat("World");
String s4 = s1.intern();
System.out.println(s1 == s2); // true
System.out.println(s1 == s3); // false
System.out.println(s1 == s4); // true
String constant "HelloWorld"
is resolved and added to SCP. s1
is assigned the SCP instance.
s1.intern()
simply returns s1
since it's already in SCP.
Result: s2 = s1
concat()
creates new instance of "HelloWorld"
in the heap, and assigns that to s3
.
Result: s3 != s1
s3.intern()
adds the string referenced by s1
to the SCP, and s2
is assigned that same reference value.
Result: s4 = s1