Why String class in Java is immutable

  • 2021-07-07 07:38:46
  • OfStack

There is no doubt that String types are immutable objects in Java, so why did the designers of Java design String types as immutable objects? This is a question worth thinking about

James Gosling, the creator of Java language, was once asked in an interview when immutable objects should be used (immutable object), and he replied that they will be used whenever they can be used.

Before that, let's briefly understand 1. What is an immutable object?

Immutable object means that after the object is created, the internal state of the object and the memory pointer address of the object cannot be changed. In Java, the final keyword is used to assist in creating immutable objects. But it should be noted that, After the basic type is modified by final, It completely becomes an immutable object, and after the reference type is modified by final, only the memory address of the pointer cannot be changed. If you want to become a completely immutable type, all the fields in the object must be declared with final, including nested objects, otherwise the internal state of the object will also change, which needs to be understood.

ok, let's analyze why String is immutable.

Through the String source code can be seen, String type of the underlying final modified by char array storage.


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

One important reason why String can be designed as an immutable type is that it is the most frequently used type of programming language. The benefits of immutable types are embodied in four aspects: caching, security, synchronization and performance.

(1) Caching

In the runtime data area of JVM, there is a special string constant pool to store literal strings, such as the following 1 code:


String s1 = "Hello World";
String s2 = "Hello World";
     
assertThat(s1 == s2).isTrue();

The memory addresses of s1 and s2 variable pointers are actually identical, That is to say, they represent the same object, This is the optimization of jvm constant pool. When the first literal quantity is declared, its value will be stored by the string constant pool. When s2 variable is declared, jvm finds that the object already exists in the constant pool, so it will not be created again, but directly assign a memory pointer to s2 variable, thus avoiding repeated creation of objects and saving memory space.

In addition, due to the immutability of string, hashCode can also be cached. In Java, hash data structures such as HashMap, HashTable and HashSet are basically String type, so hashCode of key can also be cached after the first call, and then directly used without regeneration, thus indirectly improving access efficiency.

(2) Safety

Immutability can also reduce the security problems of the application at runtime, such as the following 1 piece of code:


void criticalMethod(String userName) {
  // check
  if (!check(userName)) {
    throw new SecurityException(); 
  }
   
  // query 
  query(userName);
  
  }

In the above 1 code, after calling this method, check the user name first, and then continue to query relevant data if it is legal. If String is variable, then the attacker can change the query user name after passing check verification, so there will be security risks, and immutability can avoid and reduce this 1 situation. On the other hand, if String is mutable, other threads running at the same time may cause confusion if they modify this value.

(3) Synchronization

Because of the immutability of String type, String objects can be safely passed and accessed between multiple threads, that is to say, you can't change the value of the string itself in multiple threads, but create a new string in the heap and then operate. Of course, without final modification, you can change the reference address of this variable, that is, you can overwrite the original variable reference with the newly generated memory reference, but this is only a reference, not the value of the variable. Pay attention to this one point.

(4) Performance

In terms of performance, it has already been mentioned before, for example, the constant pool of strings saves memory, and the Hash class caches hashCode with strings as key data structure, thus improving access performance. Because strings are the most widely used data structures in programming languages, the advantages brought by the immutability of strings can be enlarged to the whole running application, thus improving the overall performance of the application.

Summary:

This paper mainly introduces why String type in Java language is designed as immutable type, And analyzes the main advantages brought by immutable types, It should be noted that although immutable types can bring many benefits, But it doesn't mean that it has no drawbacks. Every modification of immutable type needs to generate a new object in memory. From another aspect, it is not suitable to use immutable type for objects that often change, which is why Java also provides StringBuilder and StringBuffer classes with modifiable values, which often need to be weighed according to specific situations in actual development.


Related articles: