13

I am a bit confused about the intern function. I have the following code:

public class InternTest{

    public static void main(String args[]){
            String s1 = "ANEK";
            String s2 =  new String("ANEK");
            String s3 = s2.intern();
            System.out.println(s3 == s1); // True

            String s11 = "ANEK".concat("SINGH");
            String s22 = s11.intern();
            System.out.println(s11 == s22); // True

            String s4 = "nat".concat("ive");
            String s5 = s4.intern();
            System.out.println(s4 == s5); // True

            String s33 = "ma".concat("in");
            String s44 = s33.intern();
            System.out.println(s33 == s44); // false

            String s331 = "ja".concat("va");
            String s441 = s331.intern();
            System.out.println(s331 == s441); // false
    }
}

My question is regarding the output. In the third case it gives me true, but in the fourth and fifth case it gives me false. Can I known what is reason behind those output? I could not come to the conclusion that it gives false for java reserved word or key word because when I tried with en um it gives true but with by te it gives me false. Can any one tell me why?

user85421
  • 28,957
  • 10
  • 64
  • 87
Aravind E
  • 1,031
  • 3
  • 15
  • 25
  • 1
    @YCF_L intern function gives me the canonical representation the string .. – Aravind E Aug 09 '17 at 06:28
  • 3
    Why it is duplicate? It is not question about string comparing, it is about `intern` usage – ByeBye Aug 09 '17 at 06:30
  • String Interning is a method of storing only one copy of each distinct String Value, which must be immutable. In Java, String class has a public method intern() that returns a canonical representation for the string object. Java’s String class privately maintains a pool of strings, where String literals are automatically interned. And when you compare strings you should use equals not == – Fady Saad Aug 09 '17 at 06:31
  • 1
    it checks with the string constant pool and check the reference and then it compares with string.. im not comparing two different string.. i need to check the references. because there is a new reference creates for s33 and s44.. but its not creates reference for s4 and s5 .. – Aravind E Aug 09 '17 at 06:32
  • 2
    Your 2nd last statement has a typo. It should be `s331.intern()` instead of `s33.intern()` – Adeel Ansari Aug 09 '17 at 06:44
  • I still can't understand why this is considered duplicate – user85421 Aug 09 '17 at 12:50

3 Answers3

13

Well you get the output that you do because the java and main Strings are already in the pool - when you start the application there are a lot of other classes that are loaded, and some of them have already interned those Strings (before your code is reached)

I would expect native also - but I guess not, meaning no one else interns it.

This has seen some attention (that I did not expect), so I thought I would expand this a little bit. Suppose you do this:

  String left = new String(new char[] { 'h', 'e', 'y' });
  String right = left.intern();
  System.out.println(left == right);

This will print true because "hey" was not in the String pool before and was added by our left.intern(). On the other hand:

 String left = new String(new char[] { 'j', 'a', 'v', 'a' });
 String right = left.intern();
 System.out.println(left == right);

prints false because "java" was already in the pool when we called left.intern.

Eugene
  • 117,005
  • 15
  • 201
  • 306
  • The interesting thing I found is that the names of any methods I define in the class that contains the `main` method (I didn't try methods of other classes) are also already in the String pool. – Eran Aug 09 '17 at 07:08
  • @Eran making `intern` even more of a debug purpose method only... I can't imagine a single place where I would explicitly want to use it.. That's btw because the way of the parsing of the class happens most probably – Eugene Aug 09 '17 at 07:10
7

Lets see the documentation of intern():

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.

This means that if there is already a string with the given value in the pool that old string is returned, otherwise the actual string is returned. Since first three strings are not in the pool, the actual strings - s2, s11 and s4 are returned, after being added to the pool, so it's the same reference. Somehow '"main"' and '"java"' are already in the pool and intern() is returning that string instead of s33 or s331 (assuming s331.intern() for last call).

Try this:

String tmp = "ANEKSINGH";  // so this is in the pool
String s11 = "ANEK".concat("SINGH");
String s22 = s11.intern();
System.out.println(s11 == s22); // FALSE now
user85421
  • 28,957
  • 10
  • 64
  • 87
0

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.

The output which are returning true means that string is present in string pool.

The output will be true, If you intern the newly created and concated string using intern()

Example:

public class InternTest{

public static void main(String args[]){
    String s1 = "ANEK";
    String s2 =  (new String("ANEK")).intern();
    String s3 = s2.intern();
    System.out.println(s3 == s1); // True

    String s33 = ("ma".concat("in")).intern();
    String s44 = s33.intern();
    System.out.println(s33 == s44); // True

    String s331 = ("ja".concat("va")).intern();
    String s441 = s33.intern();
    System.out.println(s331 == s441); // True
}
}
Shailesh Yadav
  • 1,061
  • 1
  • 15
  • 30