Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Immutability of Strings in Java

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, String objects are immutable. Then how come the object str can be assigned value "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?

like image 618
Light_handle Avatar asked Oct 12 '09 01:10

Light_handle


People also ask

What is string immutability?

When you create a string, it is immutable. That means it is read-only. When something is immutable or read-only, it means it cannot be changed at a later time.

Why string is immutable in Java with example?

The String is immutable in Java because of the security, synchronization and concurrency, caching, and class loading. The reason of making string final is to destroy the immutability and to not allow others to extend it. The String objects are cached in the String pool, and it makes the String immutable.

What is mutable and immutable string in Java?

a mutable string can be changed, and an immutable string cannot be changed.

How does immutability work in Java?

Immutable class in java means that once an object is created, we cannot change its content. In Java, all the wrapper classes (like Integer, Boolean, Byte, Short) and String class is immutable.


2 Answers

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.

like image 192
gustafc Avatar answered Sep 18 '22 20:09

gustafc


The object that str references can change, but the actual String objects themselves cannot.

The String objects containing the string "Hello" and "Help!" cannot change their values, hence they are immutable.

The immutability of String objects does not mean that the references pointing to the object cannot change.

One way that one can prevent the str reference from changing is to declare it as final:

final String STR = "Hello"; 

Now, trying to assign another String to STR will cause a compile error.

like image 29
coobird Avatar answered Sep 21 '22 20:09

coobird