3

I know that String.intern() adds string to pool if it does not contain the object, but how to explain the results.

The code below:

public static void main(String[] args) {

        char[] abc = new char[]{'a','b','c'};
        String str = new String(abc);
        System.out.println(str == "abc");
        str.intern();
        System.out.println(str == "abc");
    }

output is :

false

false

However when code as below:

public static void main(String[] args) {

        char[] abc = new char[]{'a','b','c'};
        String str = new String(abc);
        str.intern();
        System.out.println(str == "abc");
    }

The output is:

true

What's the difference.

周雪静
  • 153
  • 1
  • 3
  • 10

1 Answers1

7

The difference is that when you use the String literal "abc" before the explicit call to intern, it is implicitly interned.

str.intern() doesn't store the instance referenced by str in the String pool if an equal String is already in the pool.

First snippet:

System.out.println(str == "abc"); // "abc" is interned
str.intern(); // str is not stored in the pool
System.out.println(str == "abc"); // returns false

Second snippet:

str.intern(); // str is stored in the pool
System.out.println(str == "abc"); // returns true

From the Javadoc of intern:

String java.lang.String.intern()

When the intern method is invoked, 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... All literal strings and string-valued constant expressions are interned.

Eran
  • 387,369
  • 54
  • 702
  • 768
  • 1
    This difference has been used in [this answer](https://stackoverflow.com/a/44929935/2711488) to detect whether a string already exists in the pool resp. when a string literal is resolved to a string object at runtime. – Holger Jan 05 '21 at 11:51