Skip to main content
replaced "equal" with "same instance"
Source Link
Max
  • 8.6k
  • 9
  • 30
  • 46

First let's look at the Java docs for 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.

Then let's look at your code:

    final String s1 = new String("aa");
    s1.intern();
    final String s2 = "aa";
    System.out.println(s1 == s2);

Here you create 3 String objects. The String literal "aa", which is added to the String pool, the new String("aa"), which is a copy constructed from "aa", but is a different instance, and the 2nd String literal "aa", which is taken from the pool again (so equal toit's the same instance as the first "aa"). When you invoke intern(), the String pool already has a String equal to s1 (the literal "aa" it was constructed from), so "aa" is returned, but you don't use it and s1 remains a different instance. Thus s1 == s2 is false.

    final String str1 = new String("str")+new String("01");
    str1.intern();
    final String str2 = "str01";
    System.out.println(str1 == str2);

Here you create 6 String objects. The literals "str" and "01", which are put into the pool. Then two copies created from those literals. Then a concatenation of those two Strings, which will be str1. This concatenation is not placed into the pool immediately, but it will be placed into the pool when you invoke intern() on str1, so str1 itself is now in the pool. So when you create str2 as String literal "str01", it will be taken from the pool, and thus be equal tothe same instance as str1.

    final String s1 = new String("aa");
    s1.intern();
    final String s2 = "aa";
    System.out.println(s1 == s2);

Here you create 3 String objects. The String literal "aa", which is added to the String pool, the new String("aa"), which is a copy constructed from "aa", but is a different instance, and the 2nd String literal "aa", which is taken from the pool again (so equal to the first "aa"). When you invoke intern(), the String pool already has a String equal to s1 (the literal "aa" it was constructed from), so "aa" is returned, but you don't use it and s1 remains a different instance. Thus s1 == s2 is false.

    final String str1 = new String("str")+new String("01");
    str1.intern();
    final String str2 = "str01";
    System.out.println(str1 == str2);

Here you create 6 String objects. The literals "str" and "01", which are put into the pool. Then two copies created from those literals. Then a concatenation of those two Strings, which will be str1. This concatenation is not placed into the pool immediately, but it will be placed into the pool when you invoke intern() on str1, so str1 itself is now in the pool. So when you create str2 as String literal "str01", it will be taken from the pool, and thus be equal to str1.

First let's look at the Java docs for 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.

Then let's look at your code:

    final String s1 = new String("aa");
    s1.intern();
    final String s2 = "aa";
    System.out.println(s1 == s2);

Here you create 3 String objects. The String literal "aa", which is added to the String pool, the new String("aa"), which is a copy constructed from "aa", but is a different instance, and the 2nd String literal "aa", which is taken from the pool again (so it's the same instance as the first "aa"). When you invoke intern(), the String pool already has a String equal to s1 (the literal "aa" it was constructed from), so "aa" is returned, but you don't use it and s1 remains a different instance. Thus s1 == s2 is false.

    final String str1 = new String("str")+new String("01");
    str1.intern();
    final String str2 = "str01";
    System.out.println(str1 == str2);

Here you create 6 String objects. The literals "str" and "01", which are put into the pool. Then two copies created from those literals. Then a concatenation of those two Strings, which will be str1. This concatenation is not placed into the pool immediately, but it will be placed into the pool when you invoke intern() on str1, so str1 itself is now in the pool. So when you create str2 as String literal "str01", it will be taken from the pool, and thus be the same instance as str1.

Source Link
Max
  • 8.6k
  • 9
  • 30
  • 46

    final String s1 = new String("aa");
    s1.intern();
    final String s2 = "aa";
    System.out.println(s1 == s2);

Here you create 3 String objects. The String literal "aa", which is added to the String pool, the new String("aa"), which is a copy constructed from "aa", but is a different instance, and the 2nd String literal "aa", which is taken from the pool again (so equal to the first "aa"). When you invoke intern(), the String pool already has a String equal to s1 (the literal "aa" it was constructed from), so "aa" is returned, but you don't use it and s1 remains a different instance. Thus s1 == s2 is false.

    final String str1 = new String("str")+new String("01");
    str1.intern();
    final String str2 = "str01";
    System.out.println(str1 == str2);

Here you create 6 String objects. The literals "str" and "01", which are put into the pool. Then two copies created from those literals. Then a concatenation of those two Strings, which will be str1. This concatenation is not placed into the pool immediately, but it will be placed into the pool when you invoke intern() on str1, so str1 itself is now in the pool. So when you create str2 as String literal "str01", it will be taken from the pool, and thus be equal to str1.