I found an interesting case while testing with string creation and checking their hashcode.
In first case i created string using copy constructor:
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
String s1 = new String("myTestString");
String s3 = s1.intern();
System.out.println("S1: " + System.identityHashCode(s1) + " S3:"
+ System.identityHashCode(s3));
}
}
Output of above code is:
S1: 816115710 S3:478684581
This is expected output as interned string picks the reference from String pool whereas s1 picks reference of new object. So their identity hash code is different.
Now if i create String using char array then i see some strange behavior:
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
char[] c1 = { 'm', 'y', 'T', 'e', 's', 't', 'S', 't', 'r', 'i', 'n',
'g' };
String s5 = new String(c1);
String s6 = s5.intern();
System.out.println("S5: " + System.identityHashCode(s5) + " S6:"
+ System.identityHashCode(s6));
}
}
Output of above code is:
S5: 816115710 S6:816115710
This is an unexpected output. How can interned String and new String object have same identityhashcode??
Any ideas?
In the first case, the myTestString
literal is on the pool before you call intern
, whereas in the second case it is not so your String s5
is put in the pool directly.
If we go through your examples step by step, this is what happens:
String s1 = new String("myTestString");
=> the use of a String literal creates a String myTestString
in the pool (let's call it s0
), and a new String s1
is also created, which is not in the pool.String s3 = s1.intern();
=> checks if there is an equivalent String in the pool and finds s0
. Now s3
and s0
refer to the same instance (i.e. s3 == s0
is true, but s1 != s0
).In your second example:
String s5 = new String(c1);
creates a new String, which is not in the poolString s6 = s5.intern();
checks if myTestString
is in the pool but can't find it, so the call to intern
creates a new String reference in the pool that refers to the same String as s5
. So s6 == s5
is true.Finally you can run these two programs to confirm my explanation (the second one prints true
three times):
public static void main(String[] args) {
String s1 = new String("myTestString");
String s3 = s1.intern();
System.out.println("myTestString" == s1);
System.out.println(s3 == s1);
System.out.println("myTestString" == s3);
}
public static void main(String[] args) {
String s1 = new String(new char[] {'m', 'y', 'T', 'e', 's', 't', 'S', 't', 'r', 'i', 'n', 'g'});
String s3 = s1.intern();
System.out.println("myTestString" == s3);
System.out.println("myTestString" == s1);
System.out.println(s3 == s1);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With