0
String s1 = new StringBuilder("dsada").append("dfgdfgd").toString();
String s3 = new StringBuilder("aaaa").toString();

System.out.println(s1.intern() == s1);  //true
System.out.println(s3.intern() == s3);  //false

the s1 and s3 finally invoke StringBuilder.toString, the method toString() contrust a new String(),and then invoke the String.intern(),the result is different,it confused me a lot.

  @Override
public String toString() {
    // Create a copy, don't share the array
    return new String(value, 0, count);
}
jason0x43
  • 3,363
  • 1
  • 16
  • 15
  • `"aaaa"` is a string literal in your code, so it's already in the interned pool. `"dsadadfgdfgd"` is not a string literal in your code, so it's added to the interned pool when you call `intern()`. – khelwood Nov 24 '21 at 12:15

1 Answers1

1

From https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/String.html#intern():

If the pool already contains a string equal to this String object as determined by the equals(Object) method, then the string from the pool is returned. Otherwise, this String object is added to the pool and a reference to this String object is returned.

"aaaa" is a string literal in your code, so it's already in the interned pool. When you call intern() on a string with value "aaaa", it returns the existing string object that it retrieved from the pool. That's not the same object as s3.

"dsadadfgdfgd" is not a string literal in your code, so when you call intern(), it adds that string object to the pool, and then returns it, the same object.

khelwood
  • 55,782
  • 14
  • 81
  • 108