I faced this question in one interview. I explained that
String is immutable and
StringBuffer is mutable class. I don't know very much about mutable and immutable and also don't know the exact answer. What are the key concepts to be able to distinguish the two ideas? Is there a performance impact when chosing one over the other?
I faced this question in one interview. I explained that
An immutable class is immutable, as in, it is not mutable. You cannot change it. If you have x::String, you can be absolutely 100% certain that x will never ever change ever (or at least, if it does, people are abusing the flexibility of your language and you have every right to tell them where to go).
A mutable class is not immutable. You can change it, other people can change it, and you can't rely on it being the same. It could be changed in another thread, you can't even be sure of it being in the same state from line to line unless you have good locking.
The ability to alter the state of the object is the key concept, but the story doesn't end there. You might want to choose an immutable class in a threaded environment, because now you don't need to worry about locking, because nobody can write to it anyway. You might want to choose immutable objects in a large system, because you can't be certain that nobody else has a handle on that input parameter and won't change it out from under you the first chance they get. You might want to choose immutable objects because they make reasoning about the behaviour of your code in small units possible--as in, if everything about a function relies on immutable data, you can look at that function in isolation, guaranteed.
There are performance impacts, but it's not all one way. Immutable objects enable a lot of optimisations you just can't do on mutable data, like aggressively sharing memory (because hey, it can't change) or more aggressive inlining. Mutable data tends to get performance increases when you need to make a lot of changes to blocks of memory.
If you're interested in seeing somewhere where immutability really shines, take a look at a language like Haskell, which was designed from the ground up for immutability, enabling language-level support for things like laziness and a lot of optimisation.
To properly define mutable and immutable classes, one must first define what it means for an object instance to be mutable. An object instance is mutable if there is any possible(*) means via which the state encapsulated thereby might be modified. An object instance is immutable if its state cannot possibly be changed. An class is immutable if all instances of that class are guaranteed to be immutable, regardless of who might hold references to them.
(*) There are certain approaches like Reflection where malicious code could modify just about anything; most discussions of immutability focus on things code may "legitimately" do, and regard such Reflection tricks as illegitimate. Outside of security applications, the normal goal is to have objects work correctly for well-behaved clients; if a class behaves oddly when clients do illegitimate things, that's the clients' problem.
Many discussions of immutability ignore the fact that while all instances of an immutable class are immutable, instances of a mutable class can also be immutable. Some discussions of mutability suggest that for a class to "really" be immutable, all fields thereof must also be immutable types. Not only is that not true, but in many cases it would represent an almost-impossible goal given the absence of immutable array types. What is necessary is that an immutable object must always be certain that no reference to any mutable object in which it holds state will ever be exposed to any code that might mutate it. Anything that outside code might legitimately want to do with the encapsulated object must be done through methods implemented by or on behalf of the immutable containing object.
It would be helpful if .NET or Java had declarative means of specifying that certain objects, despite being of mutable type, should never be modified. Unfortunately, no such feature exists. Despite that, a major key to writing correct and efficient code is knowing which references identify things which are known to be of immutable classes, which ones identify (what must be) immutable instances of possibly-mutable classes, which ones identify unshared mutable instances of mutable classes, and which ones fit none of those patterns (generally because they identify "entities"). Many kinds of bugs, some of which may be very obscure, can result from using one of the above kinds of reference as though it was another.
PS--A framework may achieve the efficiency and robustness of const validation without the hassles of C++-style "const correctness" if
Distinct storage types exist for "references to entity", "unrestricted reference to potentially-mutable value", "read-only reference to potentially-mutable value", and "reference to immutable value"
Values are cloneable [cloning could be largely automated if the types of contained references are distinguished]
Members can be marked based upon whether they should be invokable upon read-only or immutable references
Each object instance includes a flag saying whether unrestricted references to it may exist
Any reference can be implicitly converted to a read-only reference; an unrestricted reference can also be implicitly converted to an immutable reference by making a new immutable clone. A read-only reference can be implicitly converted to immutable, making a new immutable clone if needed. A new mutable object may be cloned from any reference.
An essential aspect of the "entity" versus "value" distinction would be that an object is a "value" only if either (1) it is immutable, or (2) it has a single owner, and no reference of any sort exists to the object which is not under the control of that owner. Trying to regain control over all references that might exist to an object which has ever been freely exposed to outside code would be impossible, and a strictly-compiler-enforced mechanism would probably be too restrictive to be useful, but even if things worked like C++ "const-correctness" where code could promise to behave with proper semantics even when it looked "suspicious", but any problems which resulted would be the fault of the programmer breaking his promise, that would be a significant advantage over the status quo.
Not java, but I would recommend reading Eric Lippert's articles about immutability. This issue isn't as clear cut as you might think for java. There is no inherent performance impact in choosing one over the other, although it can impact performance depending upon your exact usage.
The key concept is whether and how an object can be changed.
mutable - liable to change.
immutable - unchanging over time or unable to be changed.
Ok so we have the definitions. We know exactly what the words mean but how do they apply to programming? Let us move on to two new definitions.
mutable object - an object that is liable to change.
immutable object - an object that is unchanging over time or unable to be changed.
We can directly use the original definition when we put it in terms of object oriented programming. The final question is how do I use this in practice?
An immutable object must be initialized upon construction and rely only upon other immutable objects once initialized.
I would like to give a more clear picture on understanding the concept of Mutable and immutable class.
Mutable means whose value can be changed reverse is true for Immutable as already told.
Actually whenever you are calling constructor of any class we are actually allocating a memory space of that type of variable in heap. for e.g
String str1 = new String("john"); String str2 = str1 ; System.out.println(str1.hashCode()); System.out.println(str2.hashCode());
Here as I have called constructor of string class a memory is allocated for this variable with value as "john" and its reference code is returned to str1 varible. In the very next statement str2 is also made pointing to the same memory location.The two println statement will output the same value indicating that both variable is pointing to same memory location. Now write this code
str2 = "monk"; System.out.println(str2.hashCode());
The moment you write this line a new memory space for string type data is created in heap ,its value is set to "monk" and the reference of the same is returned to str2 and hence str2 is no more pointing to same memory location and hence you will get different hashcode value in println statement. The reason for this is "String is immutable class". So you can not change its value by any means. For StringBuffer Class you can check its mutability using this code
StringBuffer sb = new StringBuffer("mohan"); StringBuffer sb1 = sb.append(" kumar"); System.out.println(sb.hashCode()); System.out.println(sb1.hashCode()+" - "+(sb1==sb)+" - "+sb.hashCode());
Used in terms of primitives (built in type), and objects (user defined type). Immutable means you can't change the value. Mutable means you can change the value.
Many think primitive variables and object variables having a final modifier in front of them are immutable, however, this isn't exactly true. Final almost doesn't mean immutable for variables. Check out this link for a code sample http://www.siteconsortium.com/h/D0000F.php.