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.
In the String constant pool, a String object is likely to have one or many references. If several references point to the 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.
If String would not have been immutable, then String interning would not have been possible because if any variable would have changed the value, it would have been reflected in the other variables too. If String is not immutable then it would cause a severe security threat to the application.
String is an example of an immutable type. A String object always represents the same string. StringBuilder is an example of a mutable type. It has methods to delete parts of the string, insert or replace characters, etc.
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.
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:
String
"java"
and refer s1
to it.String
"java rules"
, but nothing
refers to it. So, the second String
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.
String is immutable means that you cannot change the object itself, but you can change the reference to the object.
When you execute a = "ty"
, you are actually changing the reference of a
to a new object created by the String literal "ty"
.
Changing an object means to use its methods to change one of its fields (or the fields are public and not final, so that they can be updated from outside without accessing them via methods), for example:
Foo x = new Foo("the field");
x.setField("a new field");
System.out.println(x.getField()); // prints "a new field"
While in an immutable class (declared as final, to prevent modification via inheritance)(its methods cannot modify its fields, and also the fields are always private and recommended to be final), for example String, you cannot change the current String but you can return a new String, i.e:
String s = "some text";
s.substring(0,4);
System.out.println(s); // still printing "some text"
String a = s.substring(0,4);
System.out.println(a); // prints "some"
You're changing what a
refers to. Try this:
String a="a";
System.out.println("a 1-->"+a);
String b=a;
a="ty";
System.out.println("a 2-->"+a);
System.out.println("b -->"+b);
You will see that the object to which a
and then b
refers has not changed.
If you want to prevent your code from changing which object a
refers to, try:
final String a="a";
A string is a char[]
containing a series of UTF-16 code units, an int
offset into that array, and an int
length.
For example.
String s
It creates space for a string reference. Assigning copies references around but does not modify the objects to which those references refer.
You should also be aware that
new String(s)
doesn't really do anything useful. It merely creates another instance backed by the same array, offset, and length as s
. There is very rarely a reason to do this so it is considered bad practice by most Java programmers.
Java double quoted strings like "my string"
are really references to interned String
instances so "bar"
is a reference to the same String instance regardless of how many times it appears in your code.
The "hello" creates one instance that is pooled, and the new String(...)
creates a non-pooled instance. Try System.out.println(("hello" == "hello") + "," + (new String("hello") == "hello") + "," + (new String("hello") == new String("hello")));
and you should see true,false,false
immutable means you can't not change the value of the same referance.every time you required to create new referance means new memory location. ex:
String str="abc";
str="bcd";
here, in the above code ,in the memory there are 2 blocks for storing the value.the first for value "abc" and second for "bcd".the second value is not replace to first value.
this is call the immutable.
In your example, the variable a
is just a reference to an instance of a string object. When you say a = "ty"
, you are not actually changing the string object, but rather pointing the reference at an entirely different instance of the string class.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With