Search code examples
javastringjvminternstring-constant

String.intern() shows strange result, how does it work


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.


Solution

  • 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.