background
As of JDK 1.7, the basic type constant pool and String constant pool are located in Java Heap.
The implementation of String # intern () has also changed. When it was not found in the constant pool, a copy was copied to the constant pool. After 1.7, the address reference on the heap was copied to the constant pool.
Case
String s1 = "tom";
String str = s1 + "cat";
System.out.println(str == "tomcat"); // false
Splicing string constants and variables, the compiler will call StringBuilder.append () to create a new object on the heap.
final String s1 = "tom";
String str = s1 + "cat";
System.out.println(str == "tomcat"); // true
When concatenating string literals and constants, the compilation stage will directly synthesize a string.
String str = "tom" + "cat";
System.out.println(str == "tomcat"); // true
When concatenating string literals, the compilation stage will directly synthesize a string.
String s1 = "tomcat";
String s2 = new String(s1);
System.out.println(s1 == s2); // false
The constant pool already has "tomcat", but new will create a new string object on the heap, because it must be immutable.
String s1 = new String("tomcat");
s1.intern();
String s2 = "tomcat";
System.out.println(s1 == s2); // false
Execute s1.intern (), the constant pool already has "tomcat", s1 exists on the heap.
Assign s2 to get the objects in the constant pool, which is definitely not equal to s1.
String s1 = new String("tom") + new String("cat");
s1.intern();
String s2 = "tomcat";
System.out.println(s1 == s2); // true
Execute s1.intern (), the constant pool does not have "tomcat", so a reference to "tomcat" in the heap is generated in the constant pool.
Assign s2 to get a reference to the heap "tomcat" in the constant pool, so s1 == s2.