4

Here is my code and I am now quite confuse about String pool and Heap storage by this output.

public class String1 {
    public static void main(String[] args) {
        // TODO Auto-generated method stub

        String str = "abcd";
        String str1 = "" ;

        str1=str1+"abcd";

        if(str.equals(str1))
            System.out.println("True");
        else
            System.out.println("False");

        if(str == str1)
            System.out.println("True");
        else
            System.out.println("False");
    }
}

Now, I am creating String str and will be stored in string pool (Correct me if I am getting wrong!). Now after concat str1 with string "abcd" they both have same value. So, I think str and str1 should have same reference in String pool and So, 2nd if statement should print true but it prints false.

So, my question why str and str1 not getting same reference ?

Darshit
  • 361
  • 2
  • 13
  • Look here: http://stackoverflow.com/questions/513832/how-do-i-compare-strings-in-java and http://stackoverflow.com/questions/19965895/passing-value-of-a-string-in-an-array-to-a-method-in-java/19966154#19966154 – dimas Apr 20 '16 at 06:57
  • confused !!! how this simply duplicate question got 5 **UPVOTE**! – muzahidbechara Apr 20 '16 at 07:40

3 Answers3

5

Java automatically interns (means, puts them into the String pool) String literals, not newly created Strings. See also https://stackoverflow.com/a/1855183/1611055.

Remember that Strings are immutable, so the + operator must create a new String - it can not append to the existing one. Internally, the + operator uses a StringBuilder to concatenate the strings. The final result is retrieved through StringBuilder.toString() which essentially does return new String(value, 0, count);.

This newly created String is not automatically put into the String pool.

Hence the str1 reference is different from str even though the strings have the same content. str points to a location in the string pool, while str1 points to a location on the heap.

If you add

str1 = str1.intern();

after str1 = str1 + "abcd"; to explicitly intern the newly created String, your second if statement returns true.

Alternatively, str1 = (str1 + "abcd").intern(); would have the same effect.

Community
  • 1
  • 1
Andreas Fester
  • 36,091
  • 7
  • 95
  • 123
  • You are right for intern will transfer String object from heap to pool. But i am still stuck to my question why str and str1 not getting same reference ? – Darshit Apr 20 '16 at 07:38
  • 1
    @Darshit Because the object which `str` references is stored in the pool, while the object which `str1` references is stored on the heap. – Andreas Fester Apr 20 '16 at 07:40
  • 1
    I saw internal implementation of concat method and it returns new Instance of String . Thanks !!! – Darshit Apr 20 '16 at 07:47
  • I can't find any JLS section about String pools, it only describes if two Strings can be calculated at compile-time and have the same content, they will reference to the same String object. String pool is the implementation detail of this JLS section. – Nier Apr 20 '16 at 08:11
-1

In case of strings to compare the values we should use equals method as it compares values that are present in the string variables.

But when we choose to compare string variables using == it compares the addresses of the String object not the values so it will return false even if they have same values in it.

iKing
  • 667
  • 10
  • 15
-2

you are right that the strings get added to the string pool. but == checks if both the objects are pointing to the same reference (to make it simpler pointing to the same memory location) in the string pool or not. whereas .equals() method check if the value of the both the object are same or not.

Abhishek
  • 2,485
  • 2
  • 18
  • 25
  • No strings do not automatically get added to the string pool. Only string constants and strings explicitly `intern()`-ed go there. – Erwin Bolwidt Apr 21 '16 at 01:59