-Why is String designed to be immutable?

String is immutable
Let's first introduce the matter of "String is immutable". In Java, a string is a constant. Once we create a String object, we cannot change its value, and its content cannot be changed (regardless of the special behavior of reflection).

For example, for example, we assign the value "lagou" to the string s, and then try to assign a new value to it, as shown in the following code:

String s = "rinvay";
s = "r";

It seems to change the value of the string, but behind it is actually a new string "r", and the reference of s points to the newly created string "r", the original string object "Rinvay" remained unchanged.

Similarly, if we call String's subString() or replace() methods, and at the same time point the reference of s to this newly created string, this will not change the content of the original string object, because these methods are just constructions. It’s just a new string. For example, the following example:

String rinvay = "rinvay";
rinvay = rinvay.subString(0, 4);

In the code, using rinvay.subString(0, 4) will create a new string of four letters "rinva", one letter less than the original, but this will not affect the original five "rinvay" A string of letters, that is, there are two objects "rinvay" and "rinva" in memory now .

What is the reason behind this? Let's look at some important source code of the String class:

public final class String
    implements Java.io.Serializable, Comparable<String>, CharSequence {
    
    
    /** The value is used for character storage. */
    private final char value[];
	//...
}

First of all, you can see that there is a very important attribute in it, that is, a private final char array , the name of the array is value. It stores every character of the string, and the value array is finalized, that is, once the value is assigned, the reference cannot be modified; and it can be found in the source code of String, except for the constructor , And there is no other method to modify the contents of the value array , and the permission of the value is private, and the external class cannot access it, so the value is finally made immutable.

So is it possible that there is such a situation: other classes inherit the String class, and then rewrite related methods, you can modify the value of value? In this case, isn't it mutable?

This problem is very good, but don't worry about it, because the String class is modified by final, so this String class will not be inherited, so no one can break the immutability of the String class by extending or overriding the behavior .

This is why String is immutable.

The benefits of String immutability

Then let's think about it, why did the Java language designers at the time design it like this? Of course, we are not the designers of String, nor can we study their real thoughts at the time. But we can think about what benefits would it bring if String was designed to be immutable? After summarizing, I mainly have the following four advantages .

String constant pool

The first benefit of String immutability is that you can use a string constant pool . In Java, there is the concept of a string constant pool. For example, if two string variables have the same content, they will point to the same object without creating a second new object with the same content, for example:

String s1 = "rinvay";
String s2 = "rinvay";

In fact, both s1 and s2 point to the same "rinvay" in the constant pool, as shown in the following figure:
Insert picture description here

As you can see in the figure, the two references on the left point to the same "rinvay" in the constant pool. It is precisely because of this mechanism and the fact that String is so widely used in programs, we can save a lot of money Memory space.

If you want to take advantage of the constant pool feature, this requires that String must have immutable properties, otherwise problems will arise. Let's look at the following example:

String s1 = "rinvay";
String s2 = "rinvay";
s1 = "RINVAY";
System.out.println(s2);

Let's think about it, assuming that the String object is variable, then after changing the object pointed to by s1 from lowercase "rinvay" to uppercase "RINVAY", s2 should change accordingly, so the printed s2 will also be uppercase :

RINVAY

This is not in line with our expectations, and there is also no way to realize the function of the string constant pool, because the content of the object may change constantly, and there is no way to reuse it. Assuming that this lowercase "rinvay" object has been referenced by many variables, if any one of the references is used to change the object value, then the content pointed to by the other references should not be affected. In fact, due to the immutable nature of String, the above program will still print "rinvay" in lowercase. The immutability prevents different strings from affecting each other, which is in line with our expectations.

Used as the key of HashMap

The second advantage of String immutability is that it can be easily used as the key of HashMap (or HashSet) . It is usually recommended to use immutable objects as the key of HashMap , such as String is very suitable as the key of HashMap.

For the key, the most important requirement is that it is immutable, so that we can use it to retrieve the value stored in the HashMap. Since the working principle of HashMap is Hash, that is, hashing, the object needs to always have the same Hash value in order to function normally. If the String is variable, this will bring a great risk, because once the content in the String object changes, then the Hash code should naturally change accordingly. If you use this key to search again, you won’t be able to find the previous one. That value.

Cache HashCode

The third benefit of String immutability is to cache HashCode.

The HashCode of a string is often used in Java. There is a hash attribute in the String class. The code is as follows:

/** Cache the hash code for the String */
private int hash;

This is a member variable, which holds the HashCode of the String object. Because String is immutable, once the object is created, the value of HashCode cannot be changed. We can cache HashCode. In this case, every time you want to use HashCode in the future, you don't need to recalculate it, just return the value of the cached hash directly , because it will not change, which can improve efficiency, so this makes the string very suitable Used as the key of HashMap.

For other objects of ordinary classes that do not have immutability, if you want to get its HashCode, you must recalculate it every time. In contrast, the efficiency is low.

Thread safe

The fourth advantage of String immutability is thread safety , because immutable objects must be thread-safe, and we don't need to take any additional measures on them to naturally guarantee thread safety.

Since String is immutable, it can be shared by multiple threads very safely, which is very important for multi-threaded programming, avoiding a lot of unnecessary synchronization operations.

to sum up

String is immutable, and then introduced the benefits of immutability of String, which are the use of a string constant pool, a key suitable for HashMap, cache HashCode, and thread safety.

Guess you like

Origin blog.csdn.net/Rinvay_Cui/article/details/111065533