24

This is a question that I got in an interview.

I've two strings defined as

String s1="Java";
String s2="Java";

My question is whether these two references point to the same memory location. In general, when we create identical strings (without new keyword), does the content get stored in the memory only once and all the String objects with the same content just refer to the same location, without storing the string "Java" redundantly ? The hash codes of s1 and s2 are the same. But are hashcodes dependent directly on memory location of the object?

Brian Rasmussen
  • 114,645
  • 34
  • 221
  • 317
Reshma Ratheesh
  • 267
  • 1
  • 2
  • 5

9 Answers9

26

The process of combining identical strings is called "interning", and has been done for many years by lots of language compilers, but not always. The answer to the question, especially as expanded by @GennadyVanin--Novosibirsk, depends on the language and the compiler implementation. For Java, all constant strings are interned, as required by the Java Language Specification. But that's only constant string expressions, and only when they're compiled at the same time. If you have two Java strings sufficiently separated in time and space (e.g., compiled into separate JAR files), they will not be the same object. Similarly, dynamically created Java strings (e.g., the output of various toString() methods) won't be interned unless the method specifically requests it via String.intern(). And yes, all uses of an interned string will share the same memory locations - that's a big part of why strings are interned in the first place.

As to other languages, that's a bigger question, but with all the information in these answers, I'm sure you can research it on the web. Suffice it to say that there is no universal agreement on how this ought to be done.

Ross Patterson
  • 9,527
  • 33
  • 48
  • @Ross Patterson Thank you so much !! This explains the concept well and is the perfect answer to my doubt – Reshma Ratheesh Apr 05 '13 at 07:07
  • @Ross Patterson, Thanks for mention. But my guess it is not by time and space affinity but by [the same JVM execution](http://stackoverflow.com/questions/6568905/does-the-clr-jvm-keep-one-single-intern-pool-for-all-running-net-java-apps) (since JVM can be reinstantiated). – Gennady Vanin Геннадий Ванин Apr 05 '13 at 10:26
  • 2
    Answer is not correct. All strings that have been pooled at compile time are also polled at run time by the classloader, regardless of what class or JAR they come from. – user207421 Jan 18 '17 at 12:30
  • "If you have two Java strings sufficiently separated in time and space (e.g., compiled into separate JAR files), they will not be the same object." As correctly pointed out by @EJP this is wrong and complete nonsense(what the hell time and space even mean in this context?). Please fix it. The answer below by Gennady describes all the correct rules. – Oleg Sep 16 '17 at 23:43
  • would Map work if the two strings weren't the same reference? –  Jul 27 '21 at 16:59
8
String s1="Java";
String s2="Java";
My question is whether these two references point to the same memory location  

Dumb citing §3.10.5 of Java Language Specification:

A string literal is a reference to an instance of class String (§4.3.1, §4.3.3).

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.

And read the comments to code example there:

This example illustrates six points:

  • Literal strings within the same class (§8) in the same package (§7) represent references to the same String object (§4.3.1).

  • Literal strings within different classes in the same package represent references to the same String object.

  • Literal strings within different classes in different packages likewise represent references to the same String object.

  • Strings computed by constant expressions (§15.28) are computed at compile time and then treated as if they were literals.

  • Strings computed by concatenation at run time are newly created and therefore distinct.

  • The result of explicitly interning a computed string is the same string as any pre-existing literal string with the same contents.

7

When compiler optimizes your string literals, it sees that both s1 and s2 have same value and thus you need only one string object. It's safe because String is immutable in Java.

String s1="Java";
String s2="Java";
System.out.println(s1== s2);

This gives result true because s1 and s2 points to the same object.

String Pool is the mechanism that all already defined string are stored in some 'pool' and before creating new String object compiler checks if such string is already defined.

Achintya Jha
  • 12,735
  • 2
  • 27
  • 39
  • 1
    Wrong. You can create String instances with StringBuilder, and if you create a string that´s already used elsewhere as a literal, it won´t !!! be the same string, nor same memory location. That´s why all String comparisons must be done using .equals. String is a reference type. – TheBlastOne Apr 04 '13 at 08:03
  • Only if you have assignments as shown in the question string literals are allocated only once. – TheBlastOne Apr 04 '13 at 08:04
  • @TheBlastOne You can intern the String manually: [`String#intern()`](http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#intern()). – maba Apr 04 '13 at 08:28
  • @maba Yes but if you don´t, string references referencing the "same" string are not equal. – TheBlastOne Apr 04 '13 at 08:52
  • 1
    @AchintyaJha yes "It's safe because String is immutable in Java." while Strings are immutable in Java, this does not imply it is safe to compare them using "==" in all cases. – TheBlastOne Apr 04 '13 at 11:19
  • May I cite [§3.10.5 from Java Language Specification](http://docs.oracle.com/javase/specs/jls/se7/html/jls-3.html#jls-3.10.5)? "A string literal is a reference to an instance of class String (§4.3.1, §4.3.3). 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." – Gennady Vanin Геннадий Ванин Apr 05 '13 at 04:42
  • 1
    @TheBlastOne The question and this answer are about string literals. Your comment is not. – user207421 Jan 18 '17 at 12:33
  • @EJP Yours neither :D if you prefer, I can delete those comments. – TheBlastOne Jan 18 '17 at 21:35
3

Example.

First example

String s1 = "FirstString";
String s2 = "FirstString";

 if(s1 == s2) {
   //This condition matched true because java don't make separate object for these two string. Both strings point to same reference.
 }

Second example

String s1= "FirstString";
String s2 = new String("FirstString");

if(s1.equals(s2)) {
  //This condition true because same content.
}

if(s1 == s2) {
  //This condition will be false because in this java allocate separate reference for both of them
}

Conclusion: Java check whether string exist or not. If we create the object of second string using new and have different content then its creates object and assign different reference and In case of If we don't create the object using new and have same content then its assign the same reference as first string contain.

Ajay S
  • 48,003
  • 27
  • 91
  • 111
  • 2
    Your conclusion is not correct. If you use `new` you always get a new string object, regardless of the content. – user207421 Jan 18 '17 at 12:31
0
String s1="Java";
String s2="Java"; 

Do they point to the same memory location?

I originally said "no" but in the case above, see the StringPool answer referred to below, it's actually yes..

"when we create identical strings (without new keyword), does the content get stored in the memory only once and all the String objects with the same content just refer to the same location"

...kind of see detailed answer in question "Java Strings and StringPool"

"The hash codes of s1 and s2 are the same. But are hashcodes dependent directly on memory location of the object?"

No the hashcodes depend on the content of the String

Community
  • 1
  • 1
Vorsprung
  • 32,923
  • 5
  • 39
  • 63
  • Your "No" seems to contradicts [§3.10.5 from Java Language Specification](http://docs.oracle.com/javase/specs/jls/se7/html/jls-3.html#jls-3.10.5): "A string literal is a reference to an instance of class String (§4.3.1, §4.3.3). 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." Check also examples there – Gennady Vanin Геннадий Ванин Apr 05 '13 at 05:00
  • I agree, I had it wrong about the "memory location". The linked answer about StringPool was news to me! – Vorsprung Apr 05 '13 at 08:02
  • first answer is YES. Both s1 and s2 reference variable are pointing to the same string object place in the string pool. – AmitG Apr 05 '13 at 08:07
  • @AmitG I agree, answer amended – Vorsprung Apr 05 '13 at 08:26
0

Adding to others: new keyword always forces to create a new object. If you declare like below:

String s1 = "some";
String s2 = "some";

Then using String Pooling mechanism, both references s1 and s2 will refer to the same String object with the value "some".

John Jai
  • 3,463
  • 6
  • 25
  • 32
0

When you have

String str1 = new String("BlaBla");  //In the heap!
String str2 = new String("BlaBla");  //In the heap!

then you're explicitly creating a String object through new operator (and constructor). In this case you'll have each object pointing to a different storage location.

But if you have:

String str1 = "BlaBla";        
String str2 = "BlaBla";

then you've implicit construction. Two strings literals share the same storage if they have the same values, this is because Java conserves the storage of the same strings! (Strings that have the same value)

Maroun
  • 94,125
  • 30
  • 188
  • 241
0
String s1="Java";
String s2="Java";

both points to same object. for more detail click here

Community
  • 1
  • 1
AmitG
  • 10,365
  • 5
  • 31
  • 52
-2

YES, Andrew Hare was answer on stack overflow in this link https://stackoverflow.com/a/2486195/4835894.

Basically, a string intern pool allows a runtime to save memory by preserving immutable strings in a pool so that areas of the application can reuse instances of common strings instead of creating multiple instances of it.

Community
  • 1
  • 1
Viet Anh Do
  • 449
  • 5
  • 6