net user
net user

Reputation: 593

How JVM allocates memory for String in java?

I have a scenario like this -

 String s = "abc", t="abc"; //LINE 1
 System.out.println(s==t); // definitely it would return true; //LINE 2
 s=s+"d"; t=t+"d";   //LINE 3
 System.out.println(s==t); // output would be false; but why??
 s=s.intern(); t=t.intern();
 System.out.println(s==t); // it would return true;

I wanted to know why the second print statement returned false. Please provide me any reference link which explains the same.

While creating t at line 1; intern was called and it pointed to "abc" why not intern was called at line 3?

Upvotes: 0

Views: 255

Answers (5)

default locale
default locale

Reputation: 13456

Java Language Specification explicitly covers this particular situation. Here is a quote from chapter 3.10.5. "String Literals":

Moreover, a string literal always refers to the same instance of class String. This is because string literals - or, more generally, strings that are the values of constant expressions (§15.28) - are "interned" so as to share unique instances, using the method String.intern.

As you can see, only constant expressions are interned. So, first four lines of your code are equivalent to:

String s = "abc".intern(), t="abc".intern(); 
System.out.println(s==t); 
s=s+"d".intern(); t=t+"d".intern();   
System.out.println(s==t); 

Expressions s+"d" and t+"d" aren't constant and, thus, aren't interned.

JLS even provides an example with useful notes. Here is the relevant part:

package testPackage;
class Test {
    public static void main(String[] args) {
        String hello = "Hello", lo = "lo";
        System.out.print((hello == ("Hel"+lo)));
    }
}

Output: false
Note: Strings computed by concatenation at run time are newly created and therefore distinct.

Upvotes: 0

Vivin Paliath
Vivin Paliath

Reputation: 95588

String s = "abc", t="abc";

s == t is true because Java automatically interns String literals. In this case the String literal "abc" has been interned and both s and t point to that same instance. Hence s == t is true.

s = s + "d"; t = t + "d";

Strings in Java are immutable. Hence what you are assigning to s and t are two new Strings that have been constructed. Therefore they do not point to the same instance. This is why s == t returns false.

s = s.intern(); t = t.intern();

Here you have forcibly interned the string in s.intern(). Since both s and t contain the same string values, the JVM sees that t is the same and makes it point to the same interned-instance as s. Hence s == t is true.

As a general note, establishing the equality of strings should be done via .equals() and not ==; == only compares references for reference-types and not values.

Upvotes: 4

MrTux
MrTux

Reputation: 34042

Strings are "special" Java objects.

The JVM tries to reuse the same references (that's why String s = "abc", t="abc"; causes s and t to point to the same instance), however, when working on instances (like t=t+"d") a new instance gets created, thus, the references are not the same

In order to compare strings you have to use the .equals() method.

intern() causes to create a canonical representation out of the string pool inside the String class ( http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#intern%28%29)

Upvotes: 4

Luiggi Mendoza
Luiggi Mendoza

Reputation: 85789

Because when you concatenate Strings you generate a new object reference except when they are literal Strings.

Note that the intern of both Strings point to the same literal String object reference.

Upvotes: 0

radai
radai

Reputation: 24202

java strings are immutable.

that means that when you do something like s=s+"d" youre actually creating a whole new string, and assigning it to s.

on top of that, the compiler does constant detection and allocation, so that when you write s="abc", t="abc" the compiler re-uses the same reference and your code is effectively s=t="abc"

so you start with the exact same string instance (thanks to compiler optimization) and turn it into 2 identical yet different strings, at which point s==t is false (s.equals(t) would have been true, as it compares the contents and not the address in memory).

next up is intern(). what intern() does is looks up an identical string in the string cache and returns it. if it doesnt find an identical entry it places the argument provided into the cache and returns the argument. so s=s.intern() places s into the string cache and returns it (so s is unchanged) but the following call t=t.intern() actually returns s, so that s==t again.

Upvotes: 6

Related Questions