4

I was trying to understand String#intern method. Now it has caused even more confusion.

package com;

public class Main {  
public static void main(String[] args) {  

        String s1 = new String("GFG"); // Line-1  
        String s2 = s1.concat("GFG"); // Line-2  
        s2.intern(); // Line-3
        String s4 = "GFGGFG"; // Line-4
//      s2.intern(); // Line -5
        System.out.println(s2 == s4);
  }
}

The above code prints true. If I comment line 3 and uncomment line 5 it is printed false.
For line 3 the SCP is checked and the String is added to SCP. But how did s2 equals to s4 in that case ?
s2 is still referencing to an object in heap which is pointing to SCP constant. Right ?

Can anyone please explain what is happening ? I've gone through different SO questions, but was not able to understand it still.

EDIT
I'm just trying to understand the intern method. I know the difference b/w == and equals and the latter is preferred.

Abdu Manas C A
  • 1,089
  • 1
  • 11
  • 19
  • 2
    Possible duplicate of [How do I compare strings in Java?](https://stackoverflow.com/questions/513832/how-do-i-compare-strings-in-java) – Stultuske Mar 01 '19 at 07:16
  • 1
    Because assigning String Literal searches the SCP first. When you assign `String s4 = "GFGGFG"`, the reference of `"GFGGFG"` from SCP is returned. – Ricky Mo Mar 01 '19 at 07:28

3 Answers3

3

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

Vikas Suryawanshi
  • 522
  • 1
  • 5
  • 12
1

In simple words, Intern is responsible to make exact copy of contents in memory (string constant pool). Memory will be shared for all copied contents.

By applying String.intern() on a couple of strings will ensure that all strings having same contents share same memory. For example, if a name ‘Amy’ appears 100 times, by interning you ensure only one ‘Amy’ is actually allocated memory.

To prove it, we can use an operator == (used to compare reference) and equals method (to compare content).

public class InternExample{  
public static void main(String args[]){  
String s1=new String("hello");  
String s2="hello";  
String s3=s1.intern();//returns string from pool, now it will be same as s2  
System.out.println(s1==s2);//false because reference variables are pointing to different instance  
System.out.println(s2==s3);//true because reference variables are pointing to same instance  
System.out.println(s2.equals(s3));//true because content are same
}}  

Output:

false
true
true

Explanation:

Case-1: s1 and s2 has same content but pointing to different reference in memory as new String always create new reference so it is false.

Case-2: s3 is interned or copied from s1 and pointing to same reference in memory as intern function just make a copy and keep same reference so it is true.

Case-3: s2 and s3 has same content

Muzzamil
  • 2,823
  • 2
  • 11
  • 23
1

It is very simple ... on the surface.

If you would have written:

s2 = s2.intern();

Then the location is irrelevant, always yielding s2 == s4.

What happens without the assignment seems a miracle for retrieving s2. The JVM exchanging the string of s2 under the hood. (Disassembly with javap -c did not show me something special.)

As intern is native, slow, and the JVM is involved, I am not willing to dive further in this esoteric subject of String interning; pure speculations what could be happening.

But definitely baffling, an interesting issue.

Joop Eggen
  • 107,315
  • 7
  • 83
  • 138