Search code examples
javastringintern

Java String intern function result problem


I'm learning Java now, and i read this question:What is Java String interning? - Stack Overflow
but i read other articles which provide some examples i don't understand:

    public static void main(String[] args) {
        String str2 = new String("str") + new String("01");
        str2.intern();
        String str1 = "str01";
        System.out.println(str2 == str1);  //true

        String s4 = new String("1");
        s4.intern();
        String s5 = "1";
        System.out.println(s4 == s5);   //false

        String s = new StringBuilder("aa").append("bb").toString();
        String s2 = new StringBuilder("cc").toString();
        System.out.println(s.intern() == s);    //true
        System.out.println(s2.intern() == s2);  //false
    }

the result in Java 11( it should be same in Java 8) is :

true
false
true
false

i don't know why results are different, i suppose it to be all true. can anyone explains it?


Solution

  • Let's look at what intern actually does (emphasis mine):

    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.

    When this code is run:

    str2.intern();
    

    The string pool only contains "str" and "01". str2 is "str01", which is not in the string pool, so the object that str2 refers too is added to the string pool. Therefore, when the next line is reached, since "str01" is already in the pool, str1 will refer to the same object as str2.

    Note that the reason why str2 == str1 is not because intern somehow changes which object str2 refers to. It doesn't do anything to str2. Strings are immutable after all.

    Now we can understand the first false. In the line:

    String s4 = new String("1");
    

    Because of the string literal "1", "1" is added to the string pool. Note that the object that is added to the string pool is not the same as the object to which s4 refers. Now you call s4.intern(), which does nothing to s4, and returns the object that is in the string pool. But you are ignoring the return value. This is why s4 != s5, and s4.intern() == s5.

    The reason for s2.intern() != s2 is much simpler - s2 refers to a different object than "cc" in the string pool! s2.intern() is supposed to return the object in the string pool, so of course it is not the same object!