The 1st line of code creates object str1 with content "java" init both in String pool and heap.
Actually:
- The string pool is part of the heap. (This doesn't actually relate to your misconception, but it helps to get these things straight in your head.)
- The string object corresponding to the "java" literal is created by the classloader, not by that statement. It is created when the class is loaded1 ... not when the code is run.
So, in fact that statement only creates a string object in the heap.
Now what will Str3 does?
The second statement creates a single string object ... in the heap.
As per the above explanation, the string object for the "java" literal used in this statement was created previously. (Indeed, if you look in the bytecode file, you will see that there is only one "java" string in the file's constant pool. So, the classloader won't even need to create two string instances and intern()
both of them. Only one is created and interned.)
I know it create Str3 in heap what about Str3 in String pool?
Nope. All string literals are created in the string pool, which automatically dedups them.
What does 3rd line do? Does it checks for equality in String pool or in heap area?
Nope. It tests to see if the object references are the same; i.e. if they are the same object. It doesn't actually test where they are in.
(You can't actually directly test if a String is in the pool or not. And you can't even test if an object is in the heap or not ... if the JVM provides you a way to allocate objects outside of the (regular) heap.)
I know that it gives false but my question is if Str1 and Str3 are stored in String pool == should give true right as references are same.
They aren't in the string pool. They are ordinary heap objects.
Think of it this way, the fact that ==
returns false
proves that they aren't (both) in the string pool. Because if they were both in the string pool they would have to be the same String
object.
Here is what the JLS says on string literals and identity:
"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
."
This interning happens when the class is loaded1.
1 - The specs don't say when the interning happens. It appears that recent JVMs resolve a method's reference to a String literal lazily; i.e. the interning happens the first time the method is called by the bytecode interpreter. However, this doesn't change the substance of the above explanation.