Sunday, January 30, 2022

Why String is Immutable or Final in Java? Explained

The string is Immutable in Java because String objects are cached in the String pool. Since cached String literals are shared between multiple clients there is always a risk, where one client's action would affect all other clients. For example, if one client changes the value of the String "Test" to "TEST", all other clients will also see that value as explained in the first example. Since caching of String objects was important for performance reasons this risk was avoided by making the String class Immutable. At the same time, String was made final so that no one can compromise invariant of String class like Immutability, Caching, hashcode calculation, etc by extending and overriding behaviors. Another reason why the String class is immutable could die due to HashMap.

Since Strings are very popular as the HashMap key, it's important for them to be immutable so that they can retrieve the value object which was stored in HashMap. Since HashMap works in the principle of hashing, which requires the same has value to function properly. Mutable String would produce two different hashcodes at the time of insertion and retrieval if contents of String were modified after insertion, potentially losing the value object in the map.

If you are an Indian cricket fan, you may be able to correlate with my next sentence. The string is VVS Laxman of Java, i.e. very very special class. I have not seen a single Java program that is written without using String. That's why a solid understanding of String is very important for a Java developer.

Important and popularity of String as data type, transfer object, and the mediator has also made it popular in Java interviews. Why String is immutable in Java is one of the most frequently asked String Interview questions in Java, which starts with a discussion of,  what is String, how String in Java is different than String in C and C++, and then shifted towards what is an immutable object in Java, what are the benefits of an immutable object, why do you use them and which scenarios should you use them. This question sometimes also asked, "Why String is final in Java".


On a similar note, if you are preparing for Java interviews, I would suggest you take a look at the Java Programming interview exposed book, an excellent resource for senior and mid-level Java programmers. It contains questions from all important Java topics including multi-threading, collection, GC, JVM internals, and frameworks like Spring and Hibernate, as shown below:




Why String is Final in Java? Answered

As I said, there could be many possible answers to this question, and the only designer of the String class can answer it with confidence. I was expecting some clue in Joshua Bloch's Effective Java book, but he also didn't mention it. I think the following two reasons make a lot of sense on why String class is made immutable or final in Java: 

1. String Pool

 Imagine String pool facility without making string immutable, it's not possible at all because in the case of string pool one string object/literal e.g. "Test" has referenced by many reference variables, so if any one of them change the value others will be automatic gets affected i.e. let's say
String A = "Test"
String B = "Test"

Now String B called, "Test".toUpperCase() which change the same object into "TEST", so A will also be "TEST" which is not desirable. Here is a nice diagram that shows how String literals are created in heap memory and String literal pool.

Why String is Immutable or Final in Java


2. Security

String has been widely used as a parameter for many Java classes like for opening network connection, you can pass hostname and port number as a string, you can pass database URL as a string for opening database connection, you can open any file in Java by passing the name of the file as an argument to File I/O classes.

In case, if String is not immutable, this would lead serious security threat, I mean someone can access any file for which he has authorization, and then can change the file name either deliberately or accidentally and gain access to that file. 

Because of immutability, you don't need to worry about that kind of threat. This reason also gels with, Why String class is final in Java, by making java.lang.String final, Java designer ensured that no one overrides any behavior of String class.




3. Thread safety

Since String is immutable it can safely share between many threads which are very important for multithreaded programming and to avoid any synchronization issues in Java, Immutability also makes String instance thread-safe in Java, which means you don't need to synchronize String operation externally. Another important point to note about String is the memory leak caused by SubString, which is not a thread-related issue but something to be aware of.


4. Caching

Another reason Why String is immutable in Java is to allow String to cache its hashcode, being immutable String in Java caches its hashcode, and do not calculate every time we call the hashcode method of String, which makes it very fast as a hashmap key to be used in hashmap in Java.  

This one is also suggested by  Jaroslav Sedlacek in the comments below. In short, because String is immutable, no one can change its contents once created which guarantees the hashCode of String to be the same on multiple invocations.




5. Class Loading 

Another good reason Why String is immutable in Java suggested by Dan Bergh Johnsson in comments is: The absolutely most important reason that String is immutable is that it is used by the class loading mechanism, and thus have profound and fundamental security aspects. 

Had String been mutable, a request to load "java.io.Writer" could have been changed to load "mil.vogoon.DiskErasingWriter"

In short, Security and String pool being the primary reasons for making String immutable, I believe there could be some more very convincing reasons as well, Please post those reasons as comments and I will include those on this post. 

By the way, the above reason holds good to answer, another Java interview question "Why String is final in Java".  Also to be immutable you have to be final so that your subclass doesn't break immutability.  what do you guys think?


Other Java String articles and tutorials you may like

And, if you prefer to watch than read then you can also check out this tutorial on our Youtube channel where we have talked about why String is Immutable and Final in Java. If you haven't subscribed to our Youtube channel and want to receive notifications about new tutorials, you can subscribe to our Youtube channel here. 



Thanks for reading this article so far. If you like this Java interview question and my explanation then please share it with your friends and colleagues. If you have any questions or feedback then please drop a note. 

P. S. - If you are new to Java programming and want to learn Java from scratch then you can also check out these best websites to learn Java Programming and development for free. It's a great collection of online learning platforms for Java developers. 

79 comments :

Javin @ Tibco RV Tutorial said...

Hi Sandeep,

As per my knowledge ,String pool gets created in PERM area of Java Heap , so if there are too many String there is good chance of OutOfMemoryError because garbage collection doesn't happen in PERM area of java heap.

Thanks
Javin

Javin @ Tibco RV Tutorial said...

Thanks Sandeep , Good to see you here back. Given extensive usage of String in any Java application and immutability benefit it provides as you pointed out which make it preferred choice in case of hashmap key or sharing between multiple thread everybody should know more about String Pool and behavior of String class.this is mine initiative :)

Anonymous said...

Very good. It is the same reason why String is final. If String is not final, you can always extend it so that it is no longer immutable.

Unknown said...

The absolutely most important reason that String is immutable is that it is used by the class loading mechanism, and thus have profound and fundamental security aspects.

Had String been mutable, a request to load "java.io.Writer" could have been changed to load "mil.vogoon.DiskErasingWriter".

Javin @ Tibco RV Tutorial said...

@Dan Bergh Johonsson.

You are absolutely right. Since string is used in many place to identify names (whether its class, file , network or anything else) and if you left String immutable you will end of with big security hole.

Thanks John for highlighting some important thing and adding value to this blogpost.

Jaroslav Sedlacek said...

String class is not a common class. It has a specific requirements and it is handled as special by both JVM Specification and Java Language Specification. Many language features depend on ability of String to represent constant text - some of them mentioned above.

One of the "side effect" of String immutability is an ability to cache its hash value which greatly improves String performance in hash based collections.

Javin @ Tibco RV Tutorial said...

Thanks Jaroslav Sedlacek , you really highlighted very good point "ability to cache hash value of String class". I guess that is true for wrapper class also which makes these classes very good candidate for hashMap or hashtable keys.

AhmedOsama said...

Thanks for this amazing info .
That explains why no one uses StringBuffer to hold a connection info of DB.

Javin @ Tibco RV Tutorial said...

Thanks Ahmed , good to know that you find this useful and you brought up a good example also that database connection name is also passes as string and not as mutable stringbuffer.

Javin @ Tibco RV Tutorial said...

Hi Michael,

Thanks you liked the post , yes I gonna compile the ideas/information mentioned in comments in the main article whenever time allows me.

Thanks
Javin

anshuiitk said...

Javin, Good article. Apart from the reason listed above and the pros and cons, the main reason I think why we have immutable claases like Integer String etc is because of space. As a designer you are always fighting for memory and performance, and this is a nice little feature provided by Java to make things efficient and consume less space.

http://anshuiitk.blogspot.com/

javaisfinal said...

you are absolutely correct mate above reason can be used to answer interview question "Why String is final in Java". Though final and immutable are two different thing e.g. StringBuffer is a final class in java but still mutable but Certain feature of String class will not be possible until String are final in Java. I don't say use above reason as it is but they can safely use to answer Why String is final in java.

Anonymous said...

In one of the interview , i was asked, how will you make a class emp immutable , it has some member variable, and another member variable say Salary, on which you don't have any control. In the sense the interviewer said the methods in salary class, can actually change the state of class salary.

Any answers

Anonymous said...

Hashcode could of course be cached even if Strings were mutable, the cached value would just have to be erased whenever the instance was modified. That's certainly doable. Bigger problems with mutable Strings as map keys is the mutability itself - mutable keys generally break contracts of existing Map and Set interfaces.

Radhika Kapur said...

@Anonymous: to make a class immutable which has member variables of classes which are mutable, you will have to deep clone the mutable objects so that only a copy of the mutable variables are available to any classes which creates an instance of our immutable class. So in your case you will have to write a method to deep clone your Salary class object when giving out to some other class. Read this article: http://www.javaranch.com/journal/2003/04/immutable.htm

Anonymous said...

Another reason for making String as final Class in Java is to enable String to be used as key in HashMap and Hashtable. If String was not final than any one can change value of String and object will not be retrieved from hashmap. I think this is a very convincing reason to make String final in Java, What do you think ?

Mansi said...

I agree final and immutable are almost has same effect. Whether you say String is final in Java or String is immutable in Java , reason will be same.you can't make string immutable until string is final.

Anonymous said...

garbage collection doesn't happen in PERM area of java heap?

Diya said...

Why String Class is Final or Why String Class is Immutable in Java is the same questions asked to me last week.I didn't about your blog post on String immutability or why String is a final class otherwise I would have answered that interview question quite well:)

jfolson said...

Another problem would be breaking the hashcode and comparable contracts. An object's hashcode cannot change. Neither can it's compareTo values relative to other object's.

Chandraprakash Sarathe said...

I would agree to usage of String as hashkey makes it immutable.Security aspect can be broken in multiple ways.I doubt how String helps here.

http://javaved.blogspot.com

Anonymous said...

If anybody has trouble understanding why Strings are immutable in Java (and other languages) it surely means he/she has never coded in Assembly which is really helpful for understanding a bit more about pointers, primitives, the Stack, etc.

Javin @ String split Java said...

@Anonymous, Indeed coding in Assembly is most difficult and some of Java programmer relatively newer is not even coded in C and C++ which makes them to understand recursion, data-structure, pointers concept even more difficult. immutability is relatively easier concept for them :)

Vivekanand said...

I understand your point on why String is immutable and final in Java but my questions is why String is reference type in Java , why not is just a null terminated character array or primitive type in Java like C or C++ ? Also can you please give example of String being immutable I mean what difference it make ?

Anonymous said...

Java strings are immutable due to flawed design. Witness the [lethora of mutable string-like classes since added to Java.

carrion said...

Just a quick note: final and immutable is not the same! Consider a class Foo with a final member bar and no setters for bar. I can still do stuff like this:
b=new Bar(5);
f=new Foo(b);
b.value=4;
The same problem arises when Foo passes bar to another Method outside it's class scope.

narasimha said...

can you please explain more about how string is useful for security reasons and how can we modify the string if it is mutable.

chikky said...

sir,
yes string is immutable.but my question is as follows:
class StringEx
{public static void main(String args[])
{String s1=”hello”;
string s2=”friend”;
s1=s1+s2;
System.out.println(s1);
}
}
sir, the output for the program is hellofriend
then how can we say that string is immutable bcoz as here the string is being retrived by another would you plz explain it as early as possible..

Fabrizio Benigni said...

I don't get the argument suggested by Dan Bergh Johnsson: a request to load "java.io.Writer" is either specified through the string literal (thus fixed at compile time) or through a string reference (thus modifiable regardless of the immutability of the object).

Fabrizio Benigni said...

@chikky,

you are confusing the concept of object immutability with the concept of variable immutability. When you reassign s1 you don't modify the object referenced by s1; instead, you're creating a new string object and assigning it to the variable s1.

Fabrizio Benigni said...

Regarding the concern with class loading and possibly mutable strings, I think you're confusing the reasons behind the effects of making strings immutable with the effects of the implementation choices that were enabled by the decision of making stings immutable: immutable strings allowed optimizations such as the string pool, which would not make any sense had Strings not been immutable, so obviously there wouldn't be any problem with class loading and the like in case strings were mutable, as in that case we wouldn't have string pools and modifying my string object "java.io.Writer" to "gotcha.hahaha" wouldn't have any effect on another "java.io.Writer" object.

Andy Glassman said...

The interviewer has his facts messed up. As someone pointed out before, the value[] is not copied, it is a reference. So there is NOT a new 1GB string every time you do a substring. On the other hand, if you are doing substring on a 1GB string only to keep a small substring of that, you most definitely would want to create a new String object. Otherwise you have this small string backed by a huge value[].

Javin @ split string in Java said...

not to worry Andrew, I understand :) By the way glad to welcome here and hope to see some interesting comments :)

Javin

Verhás Péter said...

Forget ALL SECURITY REASONS. As regarding security reasoning String IS mutable:

package com.verhas.elrettentopelda;

import java.lang.reflect.Field;

public class Wtf {
public static void main(String[] args) throws Exception {
String alma = "alma";
String korte = "alma";
Field value = String.class.getDeclaredField("value");
value.setAccessible(true);
value.set(alma, new char[] { 'k', 'o', 'r', 't', 'e' });
System.out.println(korte);
}
}

Deep Shah said...

Hello Dir,
As u said:
"String A = "Test"
String B = "Test"

Now String B called "Test".toUpperCase() which change the same object into "TEST" , so A will also be "TEST" which is not desirable."

I tried this example but the output of String A does not changed it's till 'Test' instead of 'TEST'

So , can u please give me the example?

Javin Paul @ sort arraylist in Java said...

Hi Deep, when you call TEST.toUpperCase(), original object will not change because String is immutable it can not be changed once created, instead a new String object will be created.

Anonymous said...

Hii Dear,

What @deep tried is true which is i also tried then how come it changes the same object when it is creating a new one. Please Explain

Niraj Singh said...

Main Reason of String being immutable is performance. Before you guys tear my opinion to shreds please read ahead :-).

Strings are backbone of Java or for that matter any other programming language. As we have seen thousand examples in this great blog itself, for example classloaders uses classname to load a class which is a string, usernames, passwords, database connection names etc. all are stored as string.

Now lets assume for a second that String were not immutable what would happen? String references pointing to litrals in constant pool would keep on changing the contents there hence a havoc would occur.

To fix this java designers would have to remove the constant pool all together. Thus we would have to create a new instance of string all the time which would go into the heaps. Tons of string would result in out of memory errors hence impact the performance of all the java applications.

Javin @ ClassLoader in Java said...

Hi Niraj, Good comment. Performance would definitely will be in mind of Java designers, because whole idea of String pool is caching. Immutability, String pool, Security, Performance these all things put together nicely for String being immutable.

Anonymous said...

If this was the answer given in an interview that I was giving, you would not get the job.
It misses the fundamental reason for using an immutable classes, and that is to allow this object to be shared efficiently without fear of having the underlying value change. All of the listed reasons are secondary to this fundamental point, so not to mention it means that you are not seeing cause and effect in the right direction.


If you take the discussion in point (5) for example, it does not make any sense. These classes were built on the assumption that String was safe to share. If they weren't safe, they would never be used in a context that required safety. It's like saying that glue is sticky because if it weren't, my furniture would fall apart.

Anonymous said...

Hi!
Honestly, I take the security argument with caution. Nothing prevents a mutable object holding the immuatable String to change the reference and so refer to another String.
More, without proper security policy, nothing prevents introspection to change an existing String value and mess up the String pool. Take a look at this code:
String titi = "titi";
String titi2 = "titi";
String titi3 = new String(titi);
Field field = String.class.getDeclaredField("value");
field.setAccessible(true);
char value[] = {'t', 'o', 't', 'o'};
field.set(titi, value);
System.out.println(titi2); // toto
System.out.println(titi3); // titi

You would expect this to fail, because the field is private and final; But this just works. More interesting, explicitly creating a new instance allow you to avoid some of the problems.

Anonymous said...

I am really unable to understand immutable(object is not modifiable) meaning..

Pls... Give me an example of mutable class and its immutability..

Thank you for noticing me.

Anonymous said...

i don't get the concept of security issue.

@Had String been mutable, a request to load "java.io.Writer" could have been changed to load "mil.vogoon.DiskErasingWriter".

if we change it, [creates a new string] won't it pass the new modified string ?

what is a value in string class that they use to access?

best students said...

yes it is a good article of final, could you please explain something about "How final method bonded during compile time and why it is called static binding "

Please ...

Nitin Taur said...

I do not very much agree with point (4) related to hashcode. Can we use an object as key in hashmap whose hashcode can change once stored in hashmap? Basically this will have same issue as with following class used as key in hashmap:

class A
{
private volatile int i = 1;
@Override
public int hashCode()
{
return ++i;
}
}

I think hashcode should never depend on changing state of object.

Anonymous said...

Good post. Only one note: the hashcode caching is not the reason for making String immutable, but visa versa hashcode caching mechanism is used because String is immutable.

Unknown said...

Java uses the concept of string literal.Suppose if there are 5 reference variables ,all references to one object.if any reference variable changes the value of an object,it will be affected to all the reference variables.That is why string is immutable in java

Manoj Mary Ranjan said...

The two main reasons why strings are immutable in many modern languages, including Java, are security and performance (or, more precisely, chance for optimizations).

The fact that strings are final is to ensure their immutability (by forbidding anyone from extending them and making them mutable again).

Anonymous said...

why do we need stringpool facility in java??

Simerpreet Singh said...

@Annonymous: We use String Pool because it stores only one reference to String literal eg.
String A = "Test"
String B = "Test"
So in String Pool there is only one instance of "Test" and variable A & B are just reference to that string. Now if you create two "Test" String using new operator eg. new String("Test") it will create a new object everytime but in case of string pool there is only one reference.So i hope you understand string pool is saving time on string related memory operations.

Unknown said...

Good post!
can you give some highlight on String Buffer and String Builder classes as both are providing mutable objects but in what aspect these are different from String class and where should we use them as compare to String class.
Thanks in advance.

Anonymous said...

A String value in Java is immutable but a String variable is not final. The term "final" specifically marks a memory reference (variable) as a constant that cannot change. The value to which a String variable refers in memory can be changed. In other words, the variable can refer to a different value, even though the original value is immutable.

Anonymous said...

Hi,
I executed below lines of code and unable to understand the output can u plz explain.
String str = "test";
String str1 = "test";
System.out.println(str);
System.out.println(str1);
"test".toUpperCase();
System.out.println(str);
System.out.println(str1);

Output Is:
test
test
test
test

According to first point str and str1 should contains "TEST".

Unknown said...

The output is right and the reason behind this is while writing "test".toUpperCase(); the value of String str become changed in to TEST but JVM didn't found any reference that refers to new value(TEST).So the reference become lost.And while printing it prints the previous value of string.If you want TEST in output then you should write
str="test".toUpperCase();
Now the reference become updated and new value of String str will be print.

javin paul said...

@vaibhav, Yes indeed, that's a side effect of making a class Immutable in Java. You need to be careful to store the modified reference otherwise it can really create hard to find bugs in your code.

Anonymous said...

Hi Javin, one more reason for String being immutable could be that String is more like the primitive type but represented as object. Since java uses pass by value it makes sense for passing an immutable object to the methods as parameter so that pass by value behavior is maintained.

Akshat

Unknown said...

how immutability of string helps in class loading??

titu said...

sorry can you please add more to following, I couldn't understand it :(


In case, if String is not immutable, this would lead serious security threat , I mean some one can access to any file for which he has authorization, and then can change the file name either deliberately or accidentally and gain access of those file. Because of immutability, you don't need to worry about those kind of threats. This reason also gel with, Why String is final in Java, by making java.lang.String final, Java designer ensured that no one overrides any behavior of String class.

Anonymous said...

@Keyur, in classloading name of class is passed as String, if String wasn't immutable its possible to change the name of that String from somewhere else, which can compromise security by loading different class.

Ansu said...

Good explanation,
need to ask one thing, Is string pool stores the hashcode of the string or only value.
if value stores in string pool then how string hashcode is stored in memory.

Anonymous said...

This line dose not make sense

String A = "Test"
String B = "Test"

Now String B called "Test".toUpperCase() which change the same object into "TEST" , so A will also be "TEST" which is not desirable.

If you do toUpperCase() to String B, why string A wll get affected?
In this example Strign A and String B will have different memory location.

javin paul said...

@Anonymous, that's the hypothetical scenario I was explaining that why its MUST for String to be final if you want to have something like String pool. I hope it make sense to you now.

Unknown said...

I believe Strings are immutable to make life easy for JVM and java team did not do it for developer/development process. I do no think any of the points are of relevance as you can always use reflection to play around with values.

Unknown said...

I have a basic question, Why the String Pool is actually provided in java?

javin paul said...

@Sapna, Java designer knows that String will be used heavily in Java application and there would be so many String object all around which will take lot of memory. To avoid that they thought about sharing String object between clients and that's why they made it Immutable and created String pool

Anonymous said...

HI Javin,

Recently interviewer asked me What is the significance of creating String using new operator if we have string literal functionality for the same ?

Do you have any thoughts on it ?

Thanks

Unknown said...

All of those posters who say String isn't immutable because they can use introspection to change its private internal state need to read up on what a SecurityManager does during the reflection call to change its value. Then load one and try to change a String's underlying value.

Just because we developers frequently ignore security doesn't mean that your code can count on reflection to allow it to do naughty things.

Rahul Kale said...

As I understand String, I don't see any use of new operator while creating String object. Can any one explain where do we need new operator to create String?

Unknown said...

When jvm is loaded into memory as instance of java.lang.Class,how much memory taken by jvm into the ram so that it can load the classes and perform their operations

Unknown said...

Thanks for your article.

Unknown said...

One advantage of making String immutable is for saving memory. When your program grows the number of String instances it creates also grows and if you don't cache String constants you end up with lots and lots of String in your heap space. By caching and sharing String constants JVM reduces lots of memory for real world Java applications.

Unknown said...

Hi here you are adding two string var so here apeend operation will take place that’s the reason you se getting this output .initially s1 and s2 are two string object when you append it will create another block of mem in heap mem to store s1+s2

Unknown said...

But in Java 8 there is no perm space then string is still immutable

Unknown said...

Actually new creates a new object each time. Literal, if the value exists in the string pool already then you will get that itself, instead of creating new object. So using Sting literal is always better and new should not be used until required.

Raja Nagendra Kumar said...

Immutability certainly leads to more memory and CPU usage if more and more new strings are created due to overcome immutability. In memory constrained and battery powered devices immutability would slow the system..

But looks like the way JVM makes use of immutability of Strings, makes programs secure, safer and faster.

DJ said...


e.g. "Test" has referenced by many reference variables, so if any one of them change the value others will be automatically gets affected i.e. lets say

String A = "Test"
String B = "Test"

Now String B called, "Test".toUpperCase() which change the same object into "TEST", so A will also be "TEST" which is not desirable.

I am confused about this point,
If I change value of B toUppercase("TEST") then it will be a new object ,then how could it affect the value of A which remains same as "Test"

Mohit Verma said...

"The string is Immutable in Java because String objects are cached in String pool" As per my knowledge this is wrong sentence the String is immutable so String object are cached in String pool.

Mohit Verma said...

I wanna ask a question then why Wrapper Class Object are immutable...

Anonymous said...

In java many value define like pie is 3.14 and if String is not immutable than if user use this than its also changed

Post a Comment