2
public class Main {
    public static void main(String[] args) {
        String a = new String("11") ;
        a.intern();
        String b = "11";
        System.out.println(a == b);                  // false

        String c = new String("2") + new String("2");
        c.intern();
        String d = "22";
        System.out.println(c == d);                  // true
    }
}

print:

false
true

I run it on the jkd 1.8 .i was so confused why the second println results .

azro
  • 53,056
  • 7
  • 34
  • 70
H.William
  • 29
  • 2
  • You never use the result of "intern", what is your code supposed to do ? – azro Apr 22 '18 at 09:25
  • @azro i check the new difference of the location of String Constant Pool .It moved to the heap.Soi want to find whether after the intern() method ,another string object in the heap has been created. – H.William Apr 22 '18 at 09:34
  • Strings are *always* in the heap memory. That’s by definition, as “heap memory” is defined by the specification as the memory where all Java object are created in. – Holger Apr 23 '18 at 08:53

1 Answers1

3

A String literal is always automatically interned the first time it appears. The String literals you have in your code are "11" and "2".

On the other hand, the String created as a result of String concatenation is not automatically interned.

String a = new String("11"); // interns the String literal "11", and creates a
                             // different String instance referenced by a
a.intern(); // doesn't add a to the String pool, since "11" is already in 
            // the String pool
String b = "11"; // "11" returns the canonical instance already in the pool,
                 // which is != a

Hence a != b.

String c = new String("2") + new String("2"); // interns the String "2", creates 2 
                                              // more Strings having the same value,
                                              // and creates an additional String
                                              // whose value is "22", which is not
                                              // interned yet
c.intern(); // c is added to the String pool as the canonical instance whose value
            // is "22"
String d = "22"; // "22" returns the canonical instance already in the pool,
                 // which is == c

Hence c == d.

All of the above follows from the Javadoc of intern:

Returns a canonical representation for the string object.

A pool of strings, initially empty, is maintained privately by the class String.

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.

It follows that for any two strings s and t, s.intern() == t.intern() is true if and only if s.equals(t) is true.

All literal strings and string-valued constant expressions are interned. String literals are defined in section 3.10.5 of the The Java™ Language Specification.

Community
  • 1
  • 1
Eran
  • 387,369
  • 54
  • 702
  • 768
  • @H.William To convince yourself that the explanation is correct, move the declaration of `d` ahead of `c`; `false` will be printed ([demo](https://ideone.com/MbzhI4)). – Sergey Kalinichenko Apr 22 '18 at 09:39
  • This can be use as a [test whether a string exists in the pool (resp. existed prior to the test)](https://stackoverflow.com/a/44929935/2711488)… – Holger Apr 23 '18 at 08:56