4

I'm new to Java and have read a conflicting statement to what I believe. Please consider the following code.

String str1 = "dave";
String str2 = "dave";

Both str1 and str2, although unique variables, reference the exact same value. So, how many unique objects are created in memory? 1 or 2 and can some one explain why?

Dave
  • 8,163
  • 11
  • 67
  • 103
  • 1
    What about trying? Open Java, and print their references after you run that code... – Benjamin Gruenbaum Mar 15 '13 at 13:48
  • 2
    Take a look at [What makes reference comparison (==) work for some strings in Java](http://stackoverflow.com/questions/9698260/what-makes-reference-comparison-work-for-some-strings-in-java) – Pshemo Mar 15 '13 at 13:51

5 Answers5

14

In your example they reference to the same object, because the strings are interned.

In general, usage of new creates new objects, thus using:

String str1 = new String("dave");
String str2 = new String("dave");

would create two different objects in the heap.

ghdalum
  • 891
  • 5
  • 17
10

It's not so complicated. Except if you're talking about Strings ;-)

First, let's ignore Strings and assume this simple type:

public class ValueHolder {
  private final int value;

  public ValueHolder(int value) {
    this.value = value;
  }

  public int getValue() {
    return value;
  }
}

If you have two lines like this:

ValueHolder vh1 = new ValueHolder(1);
ValueHolder vh2 = new ValueHolder(1);

then you'll have created exactly 2 objects on the heap. Even though they behave exactly the same and have the exact same values stored in them (and can't be modified), you will have two objects.

So vh1 == vh2 will return false!

The same is true for String objects: two String objects with the same value can exist.

However, there is one specific thing about String: if you use a String literal(*) in your code, Java will try to re-use any earlier occurance of this (via a process called interning).

So in your example code str1 and str2 will point to the same object.

(*) or more precisely: a compile-time constant expression of type String.

yshavit
  • 42,327
  • 7
  • 87
  • 124
Joachim Sauer
  • 302,674
  • 57
  • 556
  • 614
9

You have one unique Object & 2 references pointing to the same object. This is as a result of String pooling (or interning). Given that both String literals have identical content, the only way to ensure that 2 separate Objects could be created would be to to explicitly invoke one of the String constructors.

Reimeus
  • 158,255
  • 15
  • 216
  • 276
  • Does this mean though, if I changed str1, the value of str2 would also change since their pointing at the same location? – Dave Mar 15 '13 at 13:51
  • 8
    You can't _change_ `str1` (unless by reflection) as `Strings` are immutable. You can change the reference to point to a different `String` though. In this case the value of the other reference is not affected. – Reimeus Mar 15 '13 at 13:52
  • so later if I do str1 = "dave2", it actually make a new string object of "dave2" and make str1 reference to the object of "dave2"? – cwhsu Mar 15 '13 at 13:56
  • 2
    @cwhsu: exactly! (although "make a new string object" *could be replaced by* "take the correct string object out of the interned string pool", if `"dave2"` was already needed somewhere before). – Joachim Sauer Mar 15 '13 at 13:58
  • 2
    @cwhsu It will only create a new `String` of a matching one does not already exist on the pool. – Reimeus Mar 15 '13 at 13:58
  • So, in Java, a string is both a reference type and immutable? – Dave Mar 15 '13 at 14:05
  • To clarify, String is the reference `Object` data type whose instances are immutable (reflection aside). Also, the only way to guarantee that the a new `String` `Object` is actually created is to explicitly invoke one of the String constructors. – Reimeus Mar 15 '13 at 14:30
0

it depends. if you write a little test program, then there's a very good chance that they will contain the same reference, because java is trying to do you a favor by saving memory and reusing references. if str2 came from user input, then it would likely be two different references. a good way to test is to use == in a comparison. if the two are ==, then they are referencing the same memory location. if they are not, then they are two different references. this throws off a lot of beginning programmers because when they first start writing code, they use ==, see that it works, then down the road can't figure out why their comparisons aren't working.

i can't explain specifically when java does reuse references "behind the scenes" but it's related to how and when the values are created

Jeff Hawthorne
  • 568
  • 2
  • 12
0

You are writing a short-hand version of this

String str1 = new String("dave");
String str2 = new String("dave");

So str1 and str2 are different objects and may be modified separately as such

"dave", the original string, exists once only in memory, with another reference.

DAB
  • 1,631
  • 19
  • 25