Immutability of Strings in Java

immutability, java, string

Solution

`str` is not an object, it's a reference to an object. `"Hello"` and `"Help!"` are two distinct `String` objects. Thus, `str` points to a string. You can change what it points to, but not that which it points at.

Take this code, for example:

String s1 = "Hello";
String s2 = s1;
// s1 and s2 now point at the same string - "Hello"

Now, there is nothing1 we could do to `s1` that would affect the value of `s2`. They refer to the same object - the string `"Hello"` - but that object is immutable and thus cannot be altered.

If we do something like this:

s1 = "Help!";
System.out.println(s2); // still prints "Hello"

Here we see the difference between mutating an object, and changing a reference. `s2` still points to the same object as we initially set `s1` to point to. Setting `s1` to `"Help!"` only changes the reference, while the `String` object it originally referred to remains unchanged.

If strings were mutable, we could do something like this:

String s1 = "Hello";
String s2 = s1;
s1.setCharAt(1, 'a'); // Fictional method that sets character at a given pos in string
System.out.println(s2); // Prints "Hallo"

Edit to respond to OP's edit:

If you look at the source code for String.replace(char,char) (also available in src.zip in your JDK installation directory -- a pro tip is to look there whenever you wonder how something really works) you can see that what it does is the following:

- If there is one or more occurrences of `oldChar` in the current string, make a copy of the current string where all occurrences of `oldChar` are replaced with `newChar`.

- If the `oldChar` is not present in the current string, return the current string.

So yes, `"Mississippi".replace('i', '!')` creates a new `String` object. Again, the following holds:

String s1 = "Mississippi";
String s2 = s1;
s1 = s1.replace('i', '!');
System.out.println(s1); // Prints "M!ss!ss!pp!"
System.out.println(s2); // Prints "Mississippi"
System.out.println(s1 == s2); // Prints "false" as s1 and s2 are two different objects

Your homework for now is to see what the above code does if you change `s1 = s1.replace('i', '!');` to `s1 = s1.replace('Q', '!');` :)

1 Actually, it is possible to mutate strings (and other immutable objects). It requires reflection and is very, very dangerous and should never ever be used unless you're actually interested in destroying the program.

Problem

Consider the following example. ``` String str = new String(); str = "Hello"; System.out.println(str); //Prints Hello str = "Help!"; System.out.println(str); //Prints Help! ``` Now, in Java, Strings are immutable. Then how come the object `str` can be assigned with a different value like "Help!". Isn't this contradicting the immutability of strings in Java? Can anybody please explain me the exact concept of immutability? Edit: Ok. I am now getting it, but just one follow-up question. What about the following code: ``` String str = "Mississippi"; System.out.println(str); // prints Mississippi str = str.replace("i", "!"); System.out.println(str); // prints M!ss!ss!pp! ``` Does this mean that two objects are created again ("Mississippi" and "M!ss!ss!pp!") and the reference `str` points to a different object after `replace()` method?

Original source

Related problems