222

I was asked in an interview why String is immutable

I answered like this:

When we create a string in Java like String s1="hello"; then an object will be created in string pool(hello) and s1 will be pointing to hello. Now if again we do String s2="hello"; then another object will not be created, but s2 will point to hello because JVM will first check if the same object is present in string pool or not. If not present, then only a new one is created, else not.

Now if suppose Java allows string mutable then if we change s1 to hello world then s2 value will also be hello world so the Java String is immutable.

Is my answer right or wrong?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
rocking
  • 4,729
  • 9
  • 30
  • 45
  • 66
    _Why_ is always difficult to answer. The most correct answer is probably: Because the language designers figured it was a good idea. – Keppil Mar 14 '14 at 06:40
  • some reading: http://javarevisited.blogspot.fr/2010/10/why-string-is-immutable-in-java.html –  Mar 14 '14 at 06:45
  • 1
    see also, [this answer](http://stackoverflow.com/a/2069014/180100) –  Mar 14 '14 at 06:45
  • 3
    Your answer is not on the point. C++ `std::string` is mutable, but they have string pool as well (well, more correctly, character array pool). – Siyuan Ren Mar 14 '14 at 06:47
  • Usually we design classes as immutable for them being thread safe and to optimize performance and memory consumption: if class is immutable all threads can only read the class and so every instance is thread safe. Immutable class instances have no need to re-allocate memory and so they are more CPU and memory effective. – Dmitry Bychenko Mar 14 '14 at 06:51
  • @DmitryBychenko The answer I told is incorrect? – rocking Mar 14 '14 at 06:57
  • @Pawanmishra possible duplicate of question title. I do not want *why String is immutable* I am asking *Is my answer is right or not* – rocking Mar 14 '14 at 06:58
  • 3
    @rocking To be honest, whether it's right or not kind of depends on how they read it. The thing is, Java can have a string pool *because* strings are immutable. If they decided to make strings mutable then they would not have used a string pool; so it may not be accurate to say "string pool, therefore immutable strings"; it's more the other way around. The *reasons* for choosing immutable strings are outlined below, and the string pool is a working strategy *because* of that. Still, your answer is not *incorrect*, it just doesn't seem complete. You'll just have to wait and see what they say. – Jason C Mar 14 '14 at 07:05
  • (In other words; if you consider Security and Efficiency to be the primary design goals, then immutable strings are a means to meet those goals, and a string pool is an efficient implementation of immutable strings.) – Jason C Mar 14 '14 at 07:07
  • @JasonC Thanks for helping.Do you think should I wait for jDeveloper answer or you have any better answer or should I wait for other answers? – rocking Mar 14 '14 at 07:07
  • @rocking I don't have an answer that's any better than the the links in the answers below (or in the question Pawan mishra linked). It's up to you if you want to wait for more answers or not. – Jason C Mar 14 '14 at 07:09
  • Your answer is correct but some more factors are there for why string in java is immutable. [see my answer](http://stackoverflow.com/questions/22397861/why-string-is-immutable/22398222#22398222) – Alex Mathew Mar 14 '14 at 07:14
  • @rocking: Your answer is correct one (you've mentioned string pool which is the means to make String being CPU and memory effective and the string pool is that useful because String is immutable). Probably, you should have added some words on thread safety. – Dmitry Bychenko Mar 14 '14 at 07:21
  • @rocking your answer is just define how java string pool works. but the question is WHY?... why java do this....? – gifpif Mar 14 '14 at 07:45
  • @DmitryBychenko Thanks,I can now have a nice sleep – rocking Mar 14 '14 at 08:17
  • 46
    I simply cannot understand why this question was closed. The supposed related answer is not even about Java and does not address the main subject of this question, which is "why". For me this us one of those cases of an irresponsible community acting on question they know nothing about. I have nominated it to reopen. – Edwin Dalorzo Mar 14 '14 at 12:33
  • @EdwinDalorzo My question was whether the answer I gave is right or wrong but none has answered and instead they provided their answers – rocking Mar 18 '14 at 17:05
  • Another duplicate: http://stackoverflow.com/questions/1552301/immutability-of-strings-in-java – Jean-François Corbett Oct 24 '14 at 12:45
  • MYSTERY CONTINUES :-D – Bhaumik Thakkar Aug 11 '16 at 12:08
  • 1
    @rocking That is a distinction without a difference. If your answer is correct it agrees with the others, and if it isn't orrect it wouldn't be much use merely to tell you 'no' without stating the real reason why it is so. – user207421 Oct 12 '17 at 06:36

13 Answers13

191

String is immutable for several reasons, here is a summary:

  • Security: parameters are typically represented as String in network connections, database connection urls, usernames/passwords etc. If it were mutable, these parameters could be easily changed.
  • Synchronization and concurrency: making String immutable automatically makes them thread safe thereby solving the synchronization issues.
  • Caching: when compiler optimizes your String objects, it sees that if two objects have same value (a="test", and b="test") and thus you need only one string object (for both a and b, these two will point to the same object).
  • Class loading: String is used as arguments for class loading. If mutable, it could result in wrong class being loaded (because mutable objects change their state).

That being said, immutability of String only means you cannot change it using its public API. You can in fact bypass the normal API using reflection. See the answer here.

In your example, if String was mutable, then consider the following example:

  String a="stack";
  System.out.println(a);//prints stack
  a.setValue("overflow");
  System.out.println(a);//if mutable it would print overflow
Community
  • 1
  • 1
  • 19
    How to could it affect the security? – Archit Maheshwari Aug 11 '15 at 18:31
  • 2
    Can someone explain Class loading with an example if possible ? – Viraj Oct 22 '15 at 03:22
  • 10
    Concerning security, if I'm interested in changing connection parameters, it's straightforward at run-time (with a debugger, etc.). Concerning class loading, if `String` is mutable, then the class loader would take the string passed in, make a copy, and not change its copy. When thinking of a problem with mutable `java.lang.String`s, think of how C++ solves this problem (since it has mutable `std::string`s. – lmat - Reinstate Monica Jan 13 '16 at 15:48
  • 1
    Regarding security, how can a mutable string be changed when the program is running ? – MasterJoe Jul 25 '18 at 05:47
  • Since String is immutable, its hashcode is cached at the time of creation and it doesn’t need to be calculated again. – Abdul Alim Shakir Dec 05 '19 at 12:21
  • 1
    Ironically, [best practice in Java](https://stackoverflow.com/questions/8881291/why-is-char-preferred-over-string-for-passwords) is to use a `char[]` instead of a `String` for passwords, so you can zero out the array afterwards. This avoids the possibility of some other code retaining a reference to the password, and removes the password from memory immediately rather than waiting for the garbage collector. So the immutability of `String` is a security problem! – kaya3 Feb 06 '20 at 06:57
48

Java Developers decide Strings are immutable due to the following aspect design, efficiency, and security.

Design Strings are created in a special memory area in java heap known as "String Intern pool". While you creating new String (Not in the case of using String() constructor or any other String functions which internally use the String() constructor for creating a new String object; String() constructor always create new string constant in the pool unless we call the method intern()) variable it searches the pool to check whether is it already exist. If it is exist, then return reference of the existing String object. If the String is not immutable, changing the String with one reference will lead to the wrong value for the other references.

According to this article on DZone:

Security String is widely used as parameter for many java classes, e.g. network connection, opening files, etc. Were String not immutable, a connection or file would be changed and lead to serious security threat. Mutable strings could cause security problem in Reflection too, as the parameters are strings.

Efficiency The hashcode of string is frequently used in Java. For example, in a HashMap. Being immutable guarantees that hashcode will always the same, so that it can be cached without worrying the changes.That means, there is no need to calculate hashcode every time it is used.

NickL
  • 4,258
  • 2
  • 21
  • 38
Alex Mathew
  • 3,925
  • 5
  • 21
  • 25
  • 11
    Your understanding of the string pool is incorrect. String *constants* are created in the intern pool, but it's perfectly possible to have more than one string object with the same text in. I agree that strings being immutable enables pooling, but there's not as much pooling sa you've stated. – Jon Skeet May 26 '15 at 05:18
  • @JonSkeet You are right. String s1 = new String("test"); statement create new string constant in the intern pool unless we call the method intern(). Thank you for deepen my knowledge about string intern pool. – Alex Mathew May 26 '15 at 09:07
  • 2
    It's more than just using the string constructor - almost *anything* which creates a new string, e.g. substring, split, concat etc will create new strings. Compile-time constants are the special case here, not the norm... – Jon Skeet May 26 '15 at 09:09
  • @JonSkeet substring(), concat(), replace() etc are internally use String constructor for creating new string object. Thank you for improving my answer. – Alex Mathew May 26 '15 at 11:21
  • @Alex Mathew In terms of efficiency we can use a wrapper object also as key for hashmap since they are also immutable in java. – Abhilash28 Aug 12 '15 at 05:41
  • 2
    @JonSkeet - All these answers say that immutability improves "security", but don't explain how. They all link to a vague dzone article which does not help either. The answers/link don't explain how a mutable string could be changed when the code is running. Could you please explain ? – MasterJoe Jul 25 '18 at 05:44
  • @MasterJoe2 Let me tell my understanding. If you are sure your String obj is not passed/used anywhere else and used only in your DB connections, there is no need of immutability. Contrived Ex : Say you have your DB conn method which receives URL as String. Say some other class/method parses the URL from a file and passes to you. Say this calling method passes this String to some other method(say for logging) also. Now the same String obj is ref-ed by some other var in Logging class. If Logging class changes the val before you access, you ll see the changed val. – user104309 Mar 01 '20 at 18:04
43

We can not be sure of what was Java designers actually thinking while designing String but we can only conclude these reasons based on the advantages we get out of string immutability, Some of which are

1. Existence of String Constant Pool

As discussed in Why String is Stored in String Constant Pool article, every application creates too many string objects and in order to save JVM from first creating lots of string objects and then garbage collecting them. JVM stores all string objects in a separate memory area called String constant pool and reuses objects from that cached pool.

Whenever we create a string literal JVM first sees if that literal is already present in constant pool or not and if it is there, new reference will start pointing to the same object in SCP.

String a = "Naresh";
String b = "Naresh";
String c = "Naresh";

In above example string object with value Naresh will get created in SCP only once and all reference a, b, c will point to the same object but what if we try to make change in a e.g. a.replace("a", "").

Ideally, a should have value Nresh but b, c should remain unchanged because as an end user we are making the change in a only. And we know a, b, c all are pointing the same object so if we make a change in a, others should also reflect the change.

But string immutability saves us from this scenario and due to the immutability of string object string object Naresh will never change. So when we make any change in a instead of change in string object Naresh JVM creates a new object assign it to a and then make change in that object.

So String pool is only possible because of String's immutability and if String would not have been immutable, then caching string objects and reusing them would not have a possibility because any variable woulds have changed the value and corrupted others.

And That's why it is handled by JVM very specially and have been given a special memory area.

2. Thread Safety

An object is called thread-safe when multiple threads are operating on it but none of them is able to corrupt its state and object hold the same state for every thread at any point in time.

As we an immutable object cannot be modified by anyone after its creation which makes every immutable object is thread safe by default. We do not need to apply any thread safety measures to it such as creating synchronized methods.

So due to its immutable nature string object can be shared by multiple threads and even if it is getting manipulated by many threads it will not change its value.

3. Security

In every application, we need to pass several secrets e.g. user's user-name\passwords, connection URLs and in general, all of this information is passed as the string object.

Now suppose if String would not have been immutable in nature then it would cause a serious security threat to the application because these values are allowed to get changed and if it is allowed then these might get changed due to wrongly written code or any other person who have access to our variable references.

4. Class Loading

As discussed in Creating objects through Reflection in Java with Example, we can use Class.forName("class_name") method to load a class in memory which again calls other methods to do so. And even JVM uses these methods to load classes.

But if you see clearly all of these methods accepts the class name as a string object so Strings are used in java class loading and immutability provides security that correct class is getting loaded by ClassLoader.

Suppose if String would not have been immutable and we are trying to load java.lang.Object which get changed to org.theft.OurObject in between and now all of our objects have a behavior which someone can use to unwanted things.

5. HashCode Caching

If we are going to perform any hashing related operations on any object we must override the hashCode() method and try to generate an accurate hashcode by using the state of the object. If an object's state is getting changed which means its hashcode should also change.

Because String is immutable so the value one string object is holding will never get changed which means its hashcode will also not change which gives String class an opportunity to cache its hashcode during object creation.

Yes, String object caches its hashcode at the time of object creation which makes it the great candidate for hashing related operations because hashcode doesn't need to be calculated again which save us some time. This is why String is mostly used as HashMap keys.

Read More on Why String is Immutable and Final in Java.

Community
  • 1
  • 1
Naresh Joshi
  • 4,188
  • 35
  • 45
  • 1
    Regarding Security - How can the mutable string value get changed in memory ? How can another person get access to our variable references ? – MasterJoe Jul 25 '18 at 05:50
  • It is not about how one can get access to the references it is what if somebody has access to those? as mentioned "if String would not have been immutable in nature then it would cause a serious security threat to the application because these values are allowed to get changed and if it is allowed then these might get changed due to wrongly written code or any other person who have access to our variable references." – Naresh Joshi Jul 25 '18 at 16:36
  • 1
    The how matters here. Its either possible to get access to the references or not. If possible, then can you name 1-2 techniques*** (i.e. the how) that can be used to do it ? If not possible, then the point about security is not applicable. *** Example - Name one technique to attack the DB of a web app --> SQL Injection. Do you know any techniques like this for attacking the references ? – MasterJoe Jul 25 '18 at 17:31
  • As mentioned, "It can happen due to wrongly written code or any changes done by another person who has access to our variable references". e.g. Suppose String is mutable and you are writing some method which is using a string a string secret and again that string is getting passed to several another method in between and one of those methods is not written by you and that method made some changes into that string now after calling all these methods control returned your method and you are using that string again but it has been changed. – Naresh Joshi Jul 26 '18 at 05:39
  • 3
    Please disclose any [affiliations](https://stackoverflow.com/help/promotion) and do not use the site as a way to promote your site through posting. See [How do I write a good answer?](https://stackoverflow.com/help/how-to-answer). –  Dec 15 '18 at 04:51
  • @NareshJoshi Your problem description implies improper code change. An improper code change doesn't make a language "not secure enough". A developer is free to represent password field as char[], which makes it mutable. There are no known Java specific Security issues if a developer was to use char[]. So how can having a Mutable String representation cause Security issues? – Dev Amitabh Dec 06 '20 at 23:21
  • @DevAmitabh I never mentioned "the language is not secure enough", I just mentioned several secrets are stored using string and they are passed in between different methods and if String objects are not immutable then some improper code in one those methods can accidentally modify those secrets and cause problems to their caller method. – Naresh Joshi Dec 07 '20 at 15:16
21

Most important reason according to this article on DZone:

String Constant Pool ... If string is mutable, changing the string with one reference will lead to the wrong value for the other references.

Security

String is widely used as parameter for many java classes, e.g. network connection, opening files, etc. Were String not immutable, a connection or file would be changed and lead to serious security threat. ...

Hope it will help you.

NickL
  • 4,258
  • 2
  • 21
  • 38
JDGuide
  • 6,239
  • 12
  • 46
  • 64
  • @JasonC I just want to know if my answer is wrong or not.I had already attended the interview and waiting for result.If the answer told them is right then I will be selected – rocking Mar 14 '14 at 06:56
  • 1
    As per my knowledge your answer is correct, but immutable mean the reference will never be change the pointing location.All the best for your interview. – JDGuide Mar 14 '14 at 07:01
  • 1
    If accept your point #1, then all objects should be immutable. – nicomp Nov 05 '17 at 16:45
  • Hi JDeveloper, I edited your answer to give proper attribution to the source of your answer. Remember to always use block quotes for verbatim copies of content. Thanks! – NickL Nov 06 '17 at 22:18
  • The DZone article contains *major* errors about the operation of the Strign pool. It is *only* for constants. *Ergo* the stated rationale is invalid. – user207421 Feb 13 '19 at 09:51
12

IMHO, this is the most important reason:

String is Immutable in Java because String objects are cached in String pool. Since cached String literals are shared between multiple clients there is always a risk, where one client's action would affect all another client.

Ref: Why String is Immutable or Final in Java

Tho
  • 23,158
  • 6
  • 60
  • 47
5

You are right. String in java uses concept of String Pool literal. When a string is created and if the string already exists in the pool, the reference of the existing string will be returned, instead of creating a new object and returning its reference.If a string is not immutable, changing the string with one reference will lead to the wrong value for the other references.

I would add one more thing, since String is immutable, it is safe for multi threading and a single String instance can be shared across different threads. This avoid the usage of synchronization for thread safety, Strings are implicitly thread safe.

Akshay
  • 137
  • 1
  • 2
  • 9
1

String is given as immutable by Sun micro systems,because string can used to store as key in map collection. StringBuffer is mutable .That is the reason,It cannot be used as key in map object

1

The most important reason of a String being made immutable in Java is Security consideration. Next would be Caching.

I believe other reasons given here, such as efficiency, concurrency, design and string pool follows from the fact that String in made immutable. For eg. String Pool could be created because String was immutable and not the other way around.

Check Gosling interview transcript here

From a strategic point of view, they tend to more often be trouble free. And there are usually things you can do with immutables that you can't do with mutable things, such as cache the result. If you pass a string to a file open method, or if you pass a string to a constructor for a label in a user interface, in some APIs (like in lots of the Windows APIs) you pass in an array of characters. The receiver of that object really has to copy it, because they don't know anything about the storage lifetime of it. And they don't know what's happening to the object, whether it is being changed under their feet.

You end up getting almost forced to replicate the object because you don't know whether or not you get to own it. And one of the nice things about immutable objects is that the answer is, "Yeah, of course you do." Because the question of ownership, who has the right to change it, doesn't exist.

One of the things that forced Strings to be immutable was security. You have a file open method. You pass a String to it. And then it's doing all kind of authentication checks before it gets around to doing the OS call. If you manage to do something that effectively mutated the String, after the security check and before the OS call, then boom, you're in. But Strings are immutable, so that kind of attack doesn't work. That precise example is what really demanded that Strings be immutable

sss
  • 598
  • 6
  • 24
0

String class is FINAL it mean you can't create any class to inherit it and change the basic structure and make the Sting mutable.

Another thing instance variable and methods of String class that are provided are such that you can't change String object once created.

The reason what you have added doesn't make the String immutable at all.This all says how the String is stored in heap.Also string pool make the huge difference in performance

Kick
  • 4,823
  • 3
  • 22
  • 29
0

In addition to the great answers, I wanted to add a few points. Like Strings, Array holds a reference to the starting of the array so if you create two arrays arr1 and arr2 and did something like arr2 = arr1 this will make the reference of arr2 same as arr1 hence changing value in one of them will result in change of the other one for example

public class Main {
    public static void main(String[] args) {
        int[] a = {1, 2, 3, 4};
        int[] b = a;
        a[0] = 8;
        b[1] = 7;
        System.out.println("A: " + a[0] + ", B: " + b[0]);
        System.out.println("A: " + a[1] + ", B: " + b[1]);
        //outputs
        //A: 8, B: 8
        //A: 7, B: 7
    }
}

Not only that it would cause bugs in the code it also can(and will) be exploited by malicious user. Suppose if you have a system that changes the admin password. The user have to first enter the newPassword and then the oldPassword if the oldPassword is same as the adminPass the program change the password by adminPass = newPassword. let's say that the new password has the same reference as the admin password so a bad programmer may create a temp variable to hold the admin password before the users inputs data if the oldPassword is equal to temp it changes the password otherwise adminPass = temp. Someone knowing that could easily enter the new password and never enter the old password and abracadabra he has admin access. Another thing I didn't understand when learning about Strings why doesn't JVM create a new string for every object and have a unique place in memory for it and you can just do that using new String("str"); The reason you wouldn't want to always use new is because it's not memory efficient and it is slower in most cases read more.

Qeaxe
  • 81
  • 8
0

If HELLO is your String then you can't change HELLO to HILLO. This property is called immutability property.

You can have multiple pointer String variable to point HELLO String.

But if HELLO is char Array then you can change HELLO to HILLO. Eg,

char[] charArr = 'HELLO';
char[1] = 'I'; //you can do this

Answer:

Programming languages have immutable data variables so that it can be used as keys in key, value pair. String variables are used as keys/indices, so they are immutable.

Uddhav P. Gautam
  • 7,362
  • 3
  • 47
  • 64
0

This probably has little to do with security because, very differently, security practices recommend using character arrays for passwords, not strings. This is because an array can be immediately erased when no longer needed. Differently, a string cannot be erased, because it is immutable. It may take long time before it is garbage collected, and even more before the content gets overwritten.

I think that immutability was chosen to allow sharing the strings and they fragments easily. String assignment, picking a substring becomes a constant time operation, and string comparison largely also, because of the reusable hash codes that are part of the string data structure and can be compared first.

From the other side, if the original string is huge (say large XML document), picking few symbols from there may prevent the whole document from being garbage collected. Because of that later Java versions seemed moved away from this immutability. Modern C++ has both mutable (std::string) and from C++17 also immutable (std::string_view) versions.

Audrius Meškauskas
  • 20,936
  • 12
  • 75
  • 93
-2

From the Security point of view we can use this practical example:

DBCursor makeConnection(String IP,String PORT,String USER,String PASS,String TABLE) {

    // if strings were mutable IP,PORT,USER,PASS can be changed by validate function
    Boolean validated = validate(IP,PORT,USER,PASS);

    // here we are not sure if IP, PORT, USER, PASS changed or not ??
    if (validated) {
         DBConnection conn = doConnection(IP,PORT,USER,PASS);
    }

    // rest of the code goes here ....
}
darxtrix
  • 2,032
  • 2
  • 23
  • 30