To understand how String objects are created and stored, I tried the following program and I see output against which I have query. Can somebody please help?
package corejava.immutable;
public class StringTester {
public static void main(String[] args) {
// TODO Auto-generated method stub
String s1 = "Omkar Patkar";
String s2 = "Omkar Patkar";
String s3 = "Omkar" + " Patkar";
String s4 = "Omkar";
String s5 = s4 +" Patkar";
String s6 = new String("Omkar Patkar");
System.out.println("Hashcode s1 = "+s1.hashCode());
System.out.println("Hashcode s2 = "+s2.hashCode());
System.out.println("Hashcode s3 = "+s3.hashCode());
System.out.println("Hashcode s4 = "+s4.hashCode());
System.out.println("Hashcode s5 = "+s5.hashCode());
System.out.println("Hashcode s6 = "+s6.hashCode());
System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
System.out.println("Indentity Hashcode s1 = "+System.identityHashCode(s1));
System.out.println("Indentity Hashcode s2 = "+System.identityHashCode(s2));
System.out.println("Indentity Hashcode s3 = "+System.identityHashCode(s3));
System.out.println("Indentity Hashcode s4 = "+System.identityHashCode(s4));
System.out.println("Indentity Hashcode s5 = "+System.identityHashCode(s5));
System.out.println("Indentity Hashcode s6 = "+System.identityHashCode(s6));
System.out.println("Indentity Hashcode intern s6 = "+System.identityHashCode(s6.intern()));
System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
System.out.println("s1 == s2 : - "+(s1 == s2));
System.out.println("s1 == s3 : - "+(s1 == s3));
System.out.println("s1 == s4 : - "+(s1 == s4));
System.out.println("s1 == s5 : - "+(s1 == s5));
System.out.println("s1 == s6 : - "+(s1 == s6));
System.out.println("\ns2 == s3 : - "+(s2 == s3));
System.out.println("s2 == s4 : - "+(s2 == s4));
System.out.println("s2 == s5 : - "+(s2 == s5));
System.out.println("s2 == s6 : - "+(s2 == s6));
System.out.println("\ns3 == s4 : - "+(s3 == s4));
System.out.println("s3 == s5 : - "+(s3 == s5));
System.out.println("s3 == s6 : - "+(s3 == s6));
System.out.println("\ns4 == s5 : - "+(s4 == s5));
System.out.println("s4 == s6 : - "+(s4 == s6));
System.out.println("\ns5 == s6 : - "+(s5 == s6));
System.out.println("\ns1 == s6.intern() : - "+(s1 == s6.intern()));
System.out.println("s2 == s6.intern() : - "+(s2 == s6.intern()));
System.out.println("s3 == s6.intern() : - "+(s3 == s6.intern()));
System.out.println("s4 == s6.intern() : - "+(s4 == s6.intern()));
System.out.println("s5 == s6.intern() : - "+(s5 == s6.intern()));
}
}
And I get to see the following output: -
Hashcode s1 = 2062602683
Hashcode s2 = 2062602683
Hashcode s3 = 2062602683
Hashcode s4 = 76311326
Hashcode s5 = 2062602683
Hashcode s6 = 2062602683
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Indentity Hashcode s1 = 4337374
Indentity Hashcode s2 = 4337374
Indentity Hashcode s3 = 4337374
Indentity Hashcode s4 = 18019860
Indentity Hashcode s5 = 31054905
Indentity Hashcode s6 = 605645
Indentity Hashcode intern s6 = 4337374
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
s1 == s2 : - true
s1 == s3 : - true
s1 == s4 : - false
s1 == s5 : - false
s1 == s6 : - false
s2 == s3 : - true
s2 == s4 : - false
s2 == s5 : - false
s2 == s6 : - false
s3 == s4 : - false
s3 == s5 : - false
s3 == s6 : - false
s4 == s5 : - false
s4 == s6 : - false
s5 == s6 : - false
s1 == s6.intern() : - true
s2 == s6.intern() : - true
s3 == s6.intern() : - true
s4 == s6.intern() : - false
s5 == s6.intern() : - false
Identity hashcodes of s5 and s6 are different from s1, s2, s3...why is it so?
In which area of memory are these objects created? ... an Object graph will help understand ...
You have created String literals and String objects. String literals like s1 and s2 are stored in the String pool. as they are the same String they have the same reference. This is efficient.
String objects created using the
new
keyword result in an object that is stored on the heap. They are treated in the same way as any other object. Creating 2 objects with the same String value will result in 2 objects each with it's own reference. Using new does not have the same efficiencies as String literals in the String pool. Interning a String object moves it to the String pool.When you compare 2 objects using
==
you are comparing their references. Thus, comparing 2 String literals with the same value will result in the test being true. However, testing 2 objects created with the new keyword will not. This is why you should use theequals
method to compare objects.EDIT
Strings created from the concatenation of 2 String literals will result in a String literal, for example s3. Thus, s3 has the same identity hashcode as s1 and s2. However, s5 is created from a String literal and a reference to a String literal, resulting in a new object. This explains why it has a different identity hashcode.