Why is String immutable?

This has been answered a million times (I get a million results on google). But my answer is the most bestest!

The short (and correct) answer:

“Because the programmers at Sun defined it to be immutable.”

To answer we first have to define when a type is immutable.
Correct answer: “When the author says it is immutable.”

And for java.lang.String this is the case. Not just the class itself is designed to describe immutable objects. The JLS itself states:

A String object has a constant (unchanging) value.

When you are at an interview they might want to hear more than just that. In any other situation you can just reply: “Why would it not be immutable?”

Joshua Bloch states in Effective Java (2nd edition, Item 15):

Classes should be immutable unless there‚Äôs a very good reason to make them mutable.

But make sure you don’t say anything that is wrong in an interview. Here are some wrong answers:

  • Because String is final.
  • For security.
  • For performance.
  • So they can be shared.
  • Because it is a primitive type.

String is final but that’s not the only reason why it can’t be mutated. It’s even possible to alter a String using reflection:

String str = "Hello World";
Field field = String.class.getDeclaredField("value");
field.setAccessible(true);
char[] value = (char[]) field.get(str);
value[1] = 'a';
System.out.println(str); // Hallo World

Immutable Strings are better for security, but that wasn’t the reason. Other languages have mutable Strings, that doesn’t mean they are insecure. They could be Copy-On-Write.

Performance is good with immutable strings. Mutable Strings would have to be cloned all the time when you pass them around, which would be very slow. Any immutable objects are better in parallel systems.
But again the Copy-On-Write strings also have quite good performance.

The documentation says: “Because String objects are immutable they can be shared.”
It does not say: “Strings are immutable so they can be shared.”
You can pass a string to other methods, but you can do that in other languages that have mutable strings (Apple Swift, PHP, Turbo Pascal).
Only strings that are just arrays of bytes can’t be shared without unpredictable results.

Strings are regular Objects, not primitives. Arrays are Objects in Java, but there is no class that you can look at. But String are based on a regular Java class and you can read all the source code of it:
http://hg.openjdk.java.net/jdk8u/ … /java/lang/String.java

Misleading Question

The reason why this question is so hard to answer is because immutability doesn’t need to be justified. Instead we should ask for reasons when a class is mutable. In Java you have to add code to make a class immutable. That is also misleading because mutability should be something that requires more code, not the other way around.

When a class is immutable you just say so in the API and maybe you add @Immutable to the declaration. That’s enough, but you should also make it final and do some other things to ensure immutability (but that’s not the topic of this post).

Mutable objects need much more explanation on how the object can be mutated and how extending classes need to consider those changes. There needs to be clear justification on why an instance can be mutated and how this is to be handled in parallel execution.

Mutable Alternatives

Another interview question can be this:
“Why is StringBuffer/StringBuilder mutable?”

Answer: Creation of a sequence of characters is often faster with a data structure that can be modified and extended in size. The value of a String needs to be copied, while a StringBu*er only needs to change some parts of the underlying array.
When n Strings need to be concatenated (joined) you start with those n Strings. Using immutable Strings would require n-1 new Strings and only the last one is the result. Memory consumption increases exponentially.
A StringBu*er only needs an array and then creates the result. The original Strings, the StringBu*er and the result are together three times the size of the result. Memory consumption increases linearly.
StringBu*ers are used for optimization. But in high-level APIs you rarely find them.

3 thoughts on “Why is String immutable?”

Leave a Reply

Your email address will not be published. Required fields are marked *