What is meant by immutable?
Immutable means that once the constructor for an object has completed execution that instance can't be altered.
This is useful as it means you can pass references to the object around, without worrying that someone else is going to change its contents. Especially when dealing with concurrency, there are no locking issues with objects that never change
e.g.
class Foo
{
private final String myvar;
public Foo(final String initialValue)
{
this.myvar = initialValue;
}
public String getValue()
{
return this.myvar;
}
}
Foo
doesn't have to worry that the caller to getValue()
might change the text in the string.
If you imagine a similar class to Foo
, but with a StringBuilder
rather than a String
as a member, you can see that a caller to getValue()
would be able to alter the StringBuilder
attribute of a Foo
instance.
Also beware of the different kinds of immutability you might find: Eric Lippert wrote a blog article about this. Basically you can have objects whose interface is immutable but behind the scenes actual mutables private state (and therefore can't be shared safely between threads).
What does immutable mean?
It means that once you instantiate the object, you can't change its properties. In your first alert you aren't changing foo. You're creating a new string. This is why in your second alert it will show "foo" instead of oo.
Does it mean, when calling methods on
a string, it will return the modified
string, but it won't change the
initial string?
Yes. Nothing can change the string once it is created. Now this doesn't mean that you can't assign a new string object to the str
variable. You just can't change the current object that str references.
If the string was mutable, does that
mean the 2nd alert() would return oo
as well?
Technically, no, because the substring method returns a new string. Making an object mutable, wouldn't change the method. Making it mutable means that technically, you could make it so that substring would change the original string instead of creating a new one.
String is immutable. What exactly is the meaning?
Before proceeding further with the fuss of immutability, let's just take a look into the String
class and its functionality a little before coming to any conclusion.
This is how String
works:
String str = "knowledge";
This, as usual, creates a string containing "knowledge"
and assigns it a reference str
. Simple enough? Lets perform some more functions:
String s = str; // assigns a new reference to the same string "knowledge"
Lets see how the below statement works:
str = str.concat(" base");
This appends a string " base"
to str
. But wait, how is this possible, since String
objects are immutable? Well to your surprise, it is.
When the above statement is executed, the VM takes the value of String str
, i.e. "knowledge"
and appends " base"
, giving us the value "knowledge base"
. Now, since String
s are immutable, the VM can't assign this value to str
, so it creates a new String
object, gives it a value "knowledge base"
, and gives it a reference str
.
An important point to note here is that, while the String
object is immutable, its reference variable is not. So that's why, in the above example, the reference was made to refer to a newly formed String
object.
At this point in the example above, we have two String
objects: the first one we created with value "knowledge"
, pointed to by s
, and the second one "knowledge base"
, pointed to by str
. But, technically, we have three String
objects, the third one being the literal "base"
in the concat
statement.
Important Facts about String and Memory usage
What if we didn't have another reference s
to "knowledge"
? We would have lost that String
. However, it still would have existed, but would be considered lost due to having no references.
Look at one more example below
String s1 = "java";
s1.concat(" rules");
System.out.println("s1 refers to "+s1); // Yes, s1 still refers to "java"
What's happening:
- The first line is pretty straightforward: create a new
String
"java"
and refers1
to it. - Next, the VM creates another new
String
"java rules"
, but nothing
refers to it. So, the secondString
is instantly lost. We can't reach
it.
The reference variable s1
still refers to the original String
"java"
.
Almost every method, applied to a String
object in order to modify it, creates new String
object. So, where do these String
objects go? Well, these exist in memory, and one of the key goals of any programming language is to make efficient use of memory.
As applications grow, it's very common for String
literals to occupy large area of memory, which can even cause redundancy. So, in order to make Java more efficient, the JVM sets aside a special area of memory called the "String constant pool".
When the compiler sees a String
literal, it looks for the String
in the pool. If a match is found, the reference to the new literal is directed to the existing String
and no new String
object is created. The existing String
simply has one more reference. Here comes the point of making String
objects immutable:
In the String
constant pool, a String
object is likely to have one or many references. If several references point to same String
without even knowing it, it would be bad if one of the references modified that String
value. That's why String
objects are immutable.
Well, now you could say, what if someone overrides the functionality of String
class? That's the reason that the String
class is marked final
so that nobody can override the behavior of its methods.
What is immutability and why should I worry about it?
What is Immutability?
- Immutability is applied primarily to objects (strings, arrays, a custom Animal class)
- Typically, if there is an immutable version of a class, a mutable version is also available. For instance, Objective-C and Cocoa define both an NSString class (immutable) and an NSMutableString class.
- If an object is immutable, it can't be changed after it is created (basically read-only). You could think of it as "only the constructor can change the object".
This doesn't directly have anything to do with user input; not even your code can change the value of an immutable object. However, you can always create a new immutable object to replace it. Here's a pseudocode example; note that in many languages you can simply do myString = "hello";
instead of using a constructor as I did below, but I included it for clarity:
String myString = new ImmutableString("hello");
myString.appendString(" world"); // Can't do this
myString.setValue("hello world"); // Can't do this
myString = new ImmutableString("hello world"); // OK
You mention "an object that just returns information"; this doesn't automatically make it a good candidate for immutability. Immutable objects tend to always return the same value that they were constructed with, so I'm inclined to say the current time wouldn't be ideal since that changes often. However, you could have a MomentOfTime class that is created with a specific timestamp and always returns that one timestamp in the future.
Benefits of Immutabilty
If you pass an object to another function/method, you shouldn't have to worry about whether that object will have the same value after the function returns. For instance:
String myString = "HeLLo WoRLd";
String lowercasedString = lowercase(myString);
print myString + " was converted to " + lowercasedString;What if the implementation of
lowercase()
changed myString as it was creating a lowercase version? The third line wouldn't give you the result you wanted. Of course, a goodlowercase()
function wouldn't do this, but you're guaranteed this fact if myString is immutable. As such, immutable objects can help enforce good object-oriented programming practices.It's easier to make an immutable object thread-safe
- It potentially simplifies the implementation of the class (nice if you're the one writing the class)
State
If you were to take all of an object's instance variables and write down their values on paper, that would be the state of that object at that given moment. The state of the program is the state of all its objects at a given moment. State changes rapidly over time; a program needs to change state in order to continue running.
Immutable objects, however, have fixed state over time. Once created, the state of an immutable object doesn't change although the state of the program as a whole might. This makes it easier to keep track of what is happening (and see other benefits above).
What is difference between mutable and immutable String in java
Case 1:
String str = "Good";
str = str + " Morning";
In the above code you create 3 String
Objects.
- "Good" it goes into the String Pool.
- " Morning" it goes into the String Pool as well.
- "Good Morning" created by concatenating "Good" and " Morning". This guy goes on the Heap.
Note: Strings are always immutable. There is no, such thing as a mutable String. str
is just a reference which eventually points to "Good Morning". You are actually, not working on 1
object. you have 3
distinct String
Objects.
Case 2:
StringBuffer str = new StringBuffer("Good");
str.append(" Morning");
StringBuffer
contains an array of characters. It is not same as a String
.
The above code adds characters to the existing array. Effectively, StringBuffer
is mutable, its String
representation isn't.
Hashable, immutable
Hashing is the process of converting some large amount of data into a much smaller amount (typically a single integer) in a repeatable way so that it can be looked up in a table in constant-time (O(1)
), which is important for high-performance algorithms and data structures.
Immutability is the idea that an object will not change in some important way after it has been created, especially in any way that might change the hash value of that object.
The two ideas are related because objects which are used as hash keys must typically be immutable so their hash value doesn't change. If it was allowed to change then the location of that object in a data structure such as a hashtable would change and then the whole purpose of hashing for efficiency is defeated.
To really grasp the idea you should try to implement your own hashtable in a language like C/C++, or read the Java implementation of the HashMap
class.
Related Topics
How to Make an Executable Jar File
What Do 3 Dots Next to a Parameter Type Mean in Java
How to Run Unix Shell Script from Java Code
How to Parse Command Line Arguments in Java
How to Lock a File Using Java (If Possible)
How Can an App Use Files Inside the Jar For Read and Write
Equals VS Arrays.Equals in Java
Compare Two Objects With .Equals() and == Operator
How to Check If a File Exists in Java
Is There a Concise Way to Iterate Over a Stream With Indices in Java 8
What Is "String Args[]"? Parameter in Main Method Java
What Does "Possible Lossy Conversion" Mean and How to Fix It
Recursively List Files in Java
"Error: Main Method Not Found in Class Myclass, Please Define the Main Method As..."