3

we make the following String objects?

String str1 = new String("ABC");
String str2 = new String("ABC");
String str3 = "ABC";
String str4 = "ABC";

Two questions on above :

  1. system.out.println("valof str1 "+str1 ); -- it prints str1 as ABC But when we compare if(str1==str2), it compares the refrences of string object. How does jvm get to differnce?

  2. str1 has differnt reference from str2 and str3 but str3 and str4 have same references so does jvm check if the string we are going to create with equal operator(instead of new) already exists (if it exist it does not create new object just assign the same refernce to new variable i.e str4) but it does not do this verfication in case of new operator?

ildjarn
  • 62,044
  • 9
  • 127
  • 211
M Sach
  • 33,416
  • 76
  • 221
  • 314

2 Answers2

11

In Java, string literals (bare "ABC" instead of new String("ABC")) are interned. That is, there is only one copy stored in the JVM, and that is always the copy that's used. That's why they compare equal when using ==.

The following comparisons are also always true:

str1.intern() == str2.intern()
str1.intern() == str3
str2.intern() == str3
str1.intern() == str4
str2.intern() == str4
C. K. Young
  • 219,335
  • 46
  • 382
  • 435
  • FYI you can call s.intern() to intern any string. – Spike Gronim Jun 16 '11 at 18:59
  • @Spike: Indeed, I updated my answer to demonstrate that. (I had planned to put that in at the outset anyway, but since I wanted to get first post in---"Fastest Gun in the West"---I usually post something basic, then expand it within the 5-minute grace period.) – C. K. Young Jun 16 '11 at 18:59
  • Thanks chris for giving insightful explanation. But i have below queries on your explanation:- 1) if we created the str1=new String("ABC")// it is not added to pool till now .correct? but when we do str1.intern() it adds the str1 in pool My point1 is still unanswered i.e when we do if(str1==str2) it compare the reference but on printing str1 inside sys out it actually prints the value? – M Sach Jun 17 '11 at 13:14
  • @Mohit: A string doesn't need to be interned to be printed! It just needs to be interned if you want to compare using `==`. Otherwise, there is no difference whether you intern a string or not. – C. K. Young Jun 17 '11 at 15:09
  • Related: http://stackoverflow.com/questions/9698260/what-makes-reference-comparison-work-for-some-strings-in-java/9698305#9698305 – Michael Berry Nov 20 '12 at 16:51
  • 1
    @berry120 Congrats on your 56 upvotes on a more recent question. ;-) – C. K. Young Nov 20 '12 at 19:03
3

You're explicitly creating new strings and asking for distinct references when you call new String(...). If you want to get back to a single reference you can call:

str1 = str1.intern();
searlea
  • 8,173
  • 4
  • 34
  • 37