In Java, the String
object is both immutable and also a pointee (aka reference type). I’m sure there are other types/objects which are both immutable and a pointee as well and that this extends further than just Java.
I can not think where this would be desirable possibly due to my own experience I’ve only used either reference types OR immutable primitive types.
Can some one please give me a situation where it would be useful so I can get an appreciation for their meaning/value/concept.
1
An immutable reference type behaves similarly to a value type.
If String were not immutable, something like this could happen:
String a = "abc";
String b = a;
a.ReplaceCharAt(1, "X"); // this is not possible, if the type is immutable
// b is now "aXc", which might be counter-intuitive
Immutability prevents this from happening: Whenever I assign a string to a variable, I can be sure that this string won’t change until I reassign the variable.
On the other hand, we still get the benefits of reference types for String
:
- In the example above,
abc
would only be stored once in memory. - Strings can be variable in size.
The latter one is probably the main reason why Strings are reference types in Java and .NET. Often, value types are stored on the stack. To put something on the stack, the compiler needs to know its size beforehand, which is kind of difficult for strings of varying size.
6
First let’s consider why it is useful to have strings that are immutable. Consider the following sketch:
void Safe(string s)
{
if (!SecurityCheck(s)) { throw new SecurityException(); }
Dangerous(s);
}
Method Safe checks to see whether string s is “safe”. Perhaps by “safe” we mean “the user is permitted to access this database table”, or “the string contains no HTML that could be used in a cross-site scripting attack”, or whatever. Only if the string is safe is it passed to a method that does something dangerous with it.
If strings were mutable then a clever attacker could pass a “safe” string and then after the security check, mutate the string to a “dangerous” string. Getting the timing right might be tricky, but of course attackers get to try multiple times, and they only have to succeed once.
This illustrates the first value of immutable data: facts deduced in the past about the data remain true in the future. If you have an immutable queue and you ask how many elements are in it, the answer you got five thousand nanoseconds ago is still correct. This enables you to make computations with confidence.
The second great value of immutable data is that it enables persistence. By persistence I don’t mean ability to serialize to disk (though that is handy) but rather ability to re-use a portion of a data structure when building a larger data structure. If you have a large immutable tree and you would like it to be a sub-tree of a larger tree, no problem. You know that it’s not going to change, so you can safely share the data. But if you have, say, a mutable queue and you’d like to use its contents in another data structure, you’re going to have to make a copy.
That’s just a brief sketch; see my series of articles on immutable data structures for more details:
Link
4
Ahh…the blessed string, it’s the photon of the software world. Depending on how you look at it, it exhibits properties of a reference type or a value type.
The benefit of being a reference type is that you can pass it by reference. But if I declared a string as “MyConstantValueString” and I passed it to a function, I wouldn’t want that function to change the value because I’m always expecting it to be “MyConstantValueString”.
By making it immutable, you get the benefits of passing by reference (no copy needed) with the security of knowing that the string you’re pointing to will never change unless you explicitly point it to another.
There are other scenarios where this will come in handy. Think for example of a functional queue. For reference, I point you to the excellent work of Eric Lippert (it’s in C# but it’s easy enough to translate to Java, and I recommend reading that entire series, it’s pretty eye opening). Where would I want to use a functional queue and what use would it be?
Believe it or not, functional queues are useful for…well queuing. E.g. I have work that needs to be done, I need to allow clients to add work to be done while also allowing workers to pull off work and do it. Internally, the queue is immutable with only one internal writer and reader. Externally, I can avoid the synchronization by just telling the writer to add my work to the queue and moving on. The reader meanwhile can pull off a batch of items and distribute them to workers also asynchronously. This reduces bottlenecks tremendously. In fact, this is how ZeroMQ is structured.
2
A string is a pointer that points to an immutable object. The pointer itself is not immutable. Changes to strings are made by changing the pointer to point to a new immutable object.
Strings are immutable precisely so that a variable that is actually a pointer can be treated as a normal variable, rather than a pointer.
Because strings are immutable, a string object (i.e. a pointer) can be passed around, without worrying about whether the thing it is pointing to will change. That is the benefit of the system.
Your question tells me, you should really read Effective Java by Joshua Bloch. First edition is available online as PDF for free for example here as PDF (note: especially the singleton chapter is outdated, and other newer stuff is missing, so consider getting 2nd edition if you like the book). Every Java programmer, even experienced ones, who has not done so yet should go through the items of the book at least at a glance, and study carefully everything they don’t already know.
In 1st ed. Item 13 in Chapter 4 is title “Favor Immutability” and goes over the subject at more length than is sensible in an answer here. But in short, you should rather be asking, why are there reference types which are not immutable. Short list of benefits of immutability: simple in multiple ways, inherently thread-safe.
Only drawback of immutable objects is: if you want to change some property of immutable object, you must create a new object, like snippet String s=""; s=s+5;
does: It first has empty string instance, then it creates new string instance with value "5"
). Also, singletons which have changing state can’t be immutable, for obvious reason.
Let’s say variable x contains a string. And when you print the string, the output is “hello”. How could you change what printing x prints?
There are two ways: either you modify the string with the reference stored in x. Since Java strings are immutable you can’t do that. Or you change the variable x, like x = “abc”. From now on printing x will print “abc”. To prevent this make x const.
1